Her ikisi de (a)
ve (b)
tanımlanmamış davranışla sonuçlanır. Bir üye işlevi boş gösterici aracılığıyla çağırmak her zaman tanımsız bir davranıştır. İşlev statikse teknik olarak da tanımsızdır, ancak bazı anlaşmazlıklar vardır.
Anlaşılması gereken ilk şey, boş göstericiye başvurmanın neden tanımsız bir davranış olduğudur. C ++ 03'te, aslında burada biraz belirsizlik var.
Her ne kadar "tanımsız davranış bir boş gösterici sonuçlarını dereferencing" §1.9 / 4 ve §8.3.2 / 4'e hem notlarda belirtilen, açıkça belirtilmediği olmamıştı. (Notlar normatif değildir.)
Ancak, bunu §3.10 / 2'den çıkarmaya çalışabilirsiniz:
Bir değer, bir nesne veya işlevi ifade eder.
Başvuruyu kaldırırken, sonuç bir değerdir. Boş gösterici bir nesneye işaret etmez , bu nedenle lvalue kullandığımızda tanımsız davranışa sahip oluruz. Sorun, önceki cümlenin asla belirtilmemesidir, öyleyse ldeğerini "kullanmak" ne anlama gelir? Sadece onu üretmek mi, yoksa daha resmi anlamda l-değeri-değer dönüşümü gerçekleştirmek için kullanmak mı?
Ne olursa olsun, kesinlikle bir değer değerine dönüştürülemez (§4.1 / 1):
Ldeğerin başvurduğu nesne T türünde bir nesne değilse ve T'den türetilmiş türde bir nesne değilse veya nesne başlatılmamışsa, bu dönüştürmeyi gerektiren bir programın tanımsız davranışı vardır.
Burada kesinlikle tanımlanmamış bir davranış.
Belirsizlik, tanımlanmamış davranış olup olmadığından kaynaklanır, ancak geçersiz bir göstericiden gelen değeri kullanmaz (yani, bir l değeri alır, ancak onu bir r değerine dönüştürmez). Değilse int *i = 0; *i; &(*i);
, iyi tanımlanmıştır. Bu aktif bir sorundur .
Bu nedenle, katı bir "boş göstericiye başvurma, tanımsız davranış elde etme" görünümü ve zayıf bir "referans alınmayan boş gösterici kullanma, tanımsız davranış elde etme" görünümüne sahibiz.
Şimdi soruyu ele alıyoruz.
Evet, (a)
tanımlanmamış davranışla sonuçlanır. Aslında, this
boş ise, fonksiyonun içeriğinden bağımsız olarak sonuç tanımsızdır.
Bu, §5.2.5 / 3'ten itibaren:
Eğer E1
türü vardır “sınıfı X işaretçiyi,” daha sonra ifade E1->E2
eşdeğer forma dönüştürülür(*(E1)).E2;
*(E1)
katı bir yorumlama ile tanımlanmamış davranışla sonuçlanacak ve .E2
bunu bir değer değerine dönüştürerek zayıf yorumlama için tanımsız davranış haline getirecektir.
Ayrıca, doğrudan (§9.3.1 / 1) adresinden tanımlanmamış davranış olduğunu da takip eder:
Bir X sınıfının statik olmayan üye işlevi, X türünde olmayan veya X'ten türetilmiş bir türden bir nesne için çağrılırsa, davranış tanımsızdır.
Statik fonksiyonlarda, katı ve zayıf yorum farkı yaratır. Kesin olarak, tanımsızdır:
Statik bir üyeye, sınıf üyesi erişim sözdizimi kullanılarak başvurulabilir, bu durumda nesne ifadesi değerlendirilir.
Yani, sanki durağan değilmiş gibi değerlendirilir ve bir kez daha boş göstericiye başvururuz (*(E1)).E2
.
Ancak, E1
statik üye işlev çağrısında kullanılmadığından, zayıf yorumlama kullanırsak çağrı iyi tanımlanmıştır. *(E1)
bir ldeğerle sonuçlanır, statik fonksiyon çözümlenir, *(E1)
atılır ve fonksiyon çağrılır. Değer-değer dönüşümü yoktur, dolayısıyla tanımsız davranış yoktur.
C ++ 0x'de, n3126'dan itibaren belirsizlik kalır. Şimdilik güvende olun: katı yorumu kullanın.