SORU
6 Aralık 2012, PERŞEMBE


Neden = v[i ] tanımlı değil miyim?

Değerlendirme sipariş anlatılır (C 11) C standardı, §1.9.15, aşağıdaki kod örneği:

void g(int i, int* v) {
    i = v[i  ]; // the behavior is undefined
}

Kod örneğinde belirtildiği gibi, davranış tanımsızdır.

(Not: biraz farklıi i , Why is a = i i undefined and not unspecified behaviour, yapı ile başka bir sorunun cevabıolabilirburada geçerli: cevap davranışı tanımsızdır . o aslındatarihisebep ve zorunluluk değil. Ancak, bazı standart ima ediyorgerekçebu tanımsız varlık - alıntı hemen aşağıya bakın. Ayrıca, bağlantılı soru davranış verilmesini gösterirbelirtilmemişOysa bu söz konusu davranış değildir neden soruyorumiyi belirtilmiş.)

Muhakeme tanımsız davranış için standart tarafından verilen aşağıdaki gibidir:

Eğer skaler bir nesne üzerinde bir yan etkisi ya göre unsequenced ise aynı skaler bir yan etkisi veya bir nesne değeri hesaplama aynı skaler nesnenin değeri kullanarak, davranışı tanımsızdır.

Bu örnekte 7 ** ifadeyi tamamen değerlendirilmiş olacağını düşünüyorumöncebu ifadeyi v[...] değerlendirdik ve busonuçbu ifadeyi değerlendirilmesi i (artış önce), amadeğeri bu ifadeyi tamamen değerlendirilmiş sonra artan bir değer. Bu noktada (ifadeyi sonra i tamamen değerlendirilmiş, değerlendirme *12)* atama i = ... ardından alır diye düşünüyorum.

i artan anlamsız olmakla birlikte, yine de bu olması gerektiğini düşünüyorumtanımlanmış.

Neden bu tanımsız davranıştır?

CEVAP
6 Aralık 2012, PERŞEMBE


İfadeyi ben tamamen ifadeyi v önce değerlendirilecek beklerdim[...] değerlendirilir

Amanedenböyle düşünüyorsun?

Bu kod İK olmak için bir tarihsel nedeni, derleyici en iyi duruma getirmeleri yan etkileri etrafında herhangi bir yerde sıra nokta arasında hareket etmek için izin. Ne kadar az sıra noktaları, optimize etmek için potansiyel fırsatlar ama daha karışık daha fazla programcılar. Eğer kodu diyor:

a = v[i  ];

Standart niyeti kodu yayılan edilebilir

a = v[i];
  i;

iki kapıda iki yerde olabilir:

tmp = i;
  i;
a = v[tmp];

ikiden fazla olurdu.

Kodu a i. ancak o zaman "tatili" optimize ^em>ama standart zaten optimizasyon verirtarafından orijinal kodu davranış a i ne zaman tanımsız olduğunu söylüyor.

Standart kolayca i önerdiğiniz gibi atama önce değerlendirilmesi gerektiğini söyler. Bu davranış, tam olarak tanımlanmış olması ve optimizasyon yasak olurdu o zaman. Ama C ve C iş böyle yürümez.

Ayrıca pek çok örnek bu tartışmaları gündeme dikkat daha kolay SNS genel olarak daha buralarda olduğunu belli etmiyor. Bu insanların "davranış tanımlanmalı ve optimizasyon yasak." apaçık ortada olduğunu söyleyen açar Ama düşünün:

void g(int *i, int* v, int *dst) {
    *dst = v[(*i)  ];
}

Bu davranış bu fonksiyon tanımlanır i != dst, ve bu durumda istersin tüm optimizasyon alabilirsiniz (bu yüzden C99 tanıttı restrict izin ver, daha fazla iyileştirmeler daha C89 veya C). Sen optimizasyon vermek için, davranış i == dst zaman tanımlı değil. C ve C standartları, programcı tarafından beklenen bir şey değil bu tanımsız davranış arasındaki örtüşme, ve bazı durumlarda başarısız arzu edilen iyileştirmeleri yasaklayan gelince ince bir çizgide yürümek. Bu YÜZDEN bu konuda soru sayısı sorgudaki kişiler biraz daha az ve biraz daha tanımlı bir optimizasyon davranışı tercih eder, ama yine de basit bir çizgi çizin.

Bu davranış, tam olarak tanımlanmış olup kenara İK, ya da sadece iyi tanımlanmış belirli işlemleri alt ifadeleri karşılık yürütme belirtilmemiş sipariş edilmelidir olup olmadığı konusudur. C İK için de geçerli nedeni sırası puan fikri ve derleyici aslında bir kavram olması gerekmez gerçeği ile yapmakdeğiştirilmiş bir nesne, bir sonraki sıra nokta kadar değer. Yani yerine sınırlamak iyileştirici diyerek "" değer değişiklikleri de bazı belirsiz nokta, standart diyor (tefsir): (1) Herhangi bir kod kullanır değeri değiştirilmiş bir nesne önce bir sonraki sıra işaret etti LT; (2) herhangi bir kod değiştirir değiştirilmiş bir nesne var İK. Bir nesne" herhangi bir nesne. "değiştirildi ^em>son sıra taşıyıcının değerlendirilmesi yasal bir emir, bir veya daha fazla noktadan itibaren değiştirildi.

Diğer dillerde (örneğin Java) başarılı ve tamamen ifade tanımlamak yan etkileri, kesinlikle C yaklaşımına karşı bir dava var. C sadece bu davayı kabul etmez.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Booredatwork.com

    Booredatwork

    5 Ocak 2009
  • GOTO Conferences

    GOTO Confere

    3 EKİM 2011
  • Tom Megalis

    Tom Megalis

    18 NİSAN 2006