Bu, İngilizce dilinin sınırlamalarına ve standarttaki tutarsız yapıya tabi olduğumuz garip köşe durumlarından biridir. Yani en iyi ihtimalle, kanıtlamak imkansız olduğu için ikna edici bir karşı argüman yapabilirim :) 1
Sorudaki kod, iyi tanımlanmış davranış sergiliyor.
As [7.1.4] Söz temelidir, orada başlayalım:
Açıkça izleyin ayrıntılı açıklamalarda aksi belirtilmedikçe aşağıdaki ifadelerden her biri geçerlidir: bir işleve bir argüman geçersiz bir değer (varsa gibi işlev etki alanının dışında bir değere, ya da programın adres alanı dışında bir işaretçi, veya boş gösterici , [... diğer örnekler ...] ) [...] davranış tanımsız. [... diğer ifadeler ...]
Bu beceriksiz bir dildir. Yorumlardan biri, listedeki öğelerin, tek tek açıklamalar tarafından geçersiz kılınmadıkça, tüm kitaplık işlevleri için UB olduğudur. Ancak liste ayrıntılı değil açıklayıcı olduğunu belirten "gibi" ile başlar. Örneğin, dizelerin doğru boş sonlandırılmasından bahsetmez (ör strcpy
. Davranışı için kritiktir ).
Bu nedenle, 7.1.4'ün amacı / kapsamı, basitçe "geçersiz bir değerin" UB'ye yol açtığıdır ( aksi belirtilmedikçe ). Neyin "geçersiz değer" olarak sayılacağını belirlemek için her işlevin açıklamasına bakmalıyız.
Örnek 1 - strcpy
[7.21.2.3] yalnızca şunu söylüyor:
strcpy
Dize ile gösterilen fonksiyon kopyalar s2
diziye (sonlandırıcı boş karakter dahil) tarafından işaret edilen s1
. Kopyalama çakışan nesneler arasında gerçekleşirse, davranış tanımsızdır.
Boş işaretçilerden açıkça bahsetmez, ancak boş sonlandırıcılardan da bahsetmez. Bunun yerine, "ile gösterilen dizeden s2
" tek geçerli değerlerin dizeler olduğu çıkarılır (yani, boş sonlu karakter dizilerine işaretçiler).
Aslında, bu model bireysel tanımlamalarda görülebilir. Diğer bazı örnekler:
[7.6.4.1 (fenv)] Mevcut kayan noktalı ortamı depolamak gösterilen nesne tarafındanenvp
[7.12.6.4 (frexp)] int tamsayı depolamak gösterilen nesne tarafındanexp
[7.19.5.1 (fclose)] tarafından işaret edilen akışstream
Örnek 2 - printf
[7.19.6.1] şunu söylüyor %p
:
p
- Argüman, bir işaretçi olacaktır void
. İşaretçinin değeri, uygulama tanımlı bir şekilde bir dizi yazdırma karakterine dönüştürülür.
Null geçerli bir işaretçi değeridir ve bu bölüm null değerinin özel bir durum olduğunu veya işaretçinin bir nesneyi göstermesi gerektiğini açıkça belirtmez. Böylece tanımlanmış davranış.
1. Bir standart yazarı öne çıkmadıkça veya olayları açıklığa kavuşturan bir mantık belgesine benzer bir şey bulamadıkça .