Cevap şudur: hangi C ++ standardına karşı derlediğinize bağlıdır. Tüm kod, bu satır haricinde tüm standartlarda mükemmel şekilde biçimlendirilmiştir:
char * s = "My String";
Şimdi, dize değişmezinin türü var const char[10]ve biz ona const olmayan bir gösterici başlatmaya çalışıyoruz. charDize değişmezleri ailesi dışındaki tüm diğer türler için , böyle bir başlatma her zaman yasadışıdır. Örneğin:
const int arr[] = {1};
int *p = arr; // nope!
Bununla birlikte, C ++ 11 öncesi, dize değişmezleri için, §4.2 / 2'de bir istisna vardı:
Geniş dize değişmezi olmayan bir dizge değeri (2.13.4), " işaretçi karakter " türünde bir rvalue değerine dönüştürülebilir ; [...]. Her iki durumda da sonuç, dizinin ilk elemanına bir göstericidir. Bu dönüştürme, yalnızca açık bir uygun işaretçi hedef türü olduğunda ve bir l değerinden bir r değerine dönüştürmeye genel bir ihtiyaç olduğunda dikkate alınmaz. [Not: bu dönüşüm kullanımdan kaldırıldı . Ek D'ye bakınız. ]
Dolayısıyla C ++ 03'te kod mükemmeldir (kullanımdan kaldırılmış olsa da) ve net, öngörülebilir davranışa sahiptir.
C ++ 11'de, bu blok mevcut değildir - dönüştürülen dize değişmezleri için böyle bir istisna yoktur. char* ve bu nedenle kod, az önce int*verdiğim örnek kadar biçimsizdir . Derleyici bir tanılama yayınlamak zorundadır ve ideal olarak, bunun gibi C ++ tipi sistemin açık ihlalleri olan durumlarda, iyi bir derleyicinin sadece bu konuda uyumlu olmasını değil (örneğin bir uyarı yayınlayarak) başarısız olmasını bekleriz. düpedüz.
Kod ideal olarak derlenmemelidir - ancak hem gcc hem de clang'da işe yarar (sanırım, bu tür sistem deliğinin on yıldan fazla bir süredir kullanımdan kaldırılmasına rağmen, muhtemelen az kazançla kırılacak çok sayıda kod var). Kod kötü biçimlidir ve bu nedenle kodun davranışının ne olabileceği konusunda mantık yürütmek mantıklı değildir. Ancak bu özel durumu ve daha önce izin verilen geçmişini göz önünde bulundurarak, ortaya çıkan kodu örtük bir const_castşeymiş gibi yorumlamanın mantıksız bir uzantı olduğuna inanmıyorum, şöyle bir şey:
const int arr[] = {1};
int *p = const_cast<int*>(arr); // OK, technically
Bununla, programın geri kalanı mükemmel bir şekilde, çünkü bir daha asla dokunmuyorsunuz s. Oluşturulmuş bir nesneyi işaretçi olmayan bir şekilde okumak tamamen tamamdır. Oluşturulmuş bir nesneyi böyle bir işaretçi aracılığıyla yazmak tanımsız bir davranıştır:constconstconst
std::cout << *p; // fine, prints 1
*p = 5; // will compile, but undefined behavior, which
// certainly qualifies as "unpredictable"
sKodunuzun herhangi bir yerinde herhangi bir değişiklik olmadığından, program C ++ 03'te iyidir, C ++ 11'de derlenemez, ancak yine de yapar - ve derleyicilerin buna izin verdiği göz önüne alındığında, içinde hala tanımlanmamış bir davranış yoktur † . Derleyicilerin hala C ++ 03 kurallarını [yanlış] yorumladıkları izinlerle, "öngörülemeyen" davranışa yol açacak hiçbir şey görmüyorum. sYine de yazın ve tüm bahisler kapanır. Hem C ++ 03 hem de C ++ 11'de.
† Yine de, tanım gereği kötü biçimlendirilmiş kod makul davranış beklentisi
sağlamaz not Olmazsa , Matt McNabb'ın cevabına bakın