C ++ 20 standart taslağının [basic.scope.pdecl] / 1'inde bir notta (normatif olmayan) bir örnek vardı ( 3580 çekme isteğinin birleştirilmesinden önceki kısmi alıntı ), bu sorunun cevabına bakın):
unsigned char x = x;
[...] x kendi (belirsiz) değeri ile başlatılır.
Bu aslında C ++ 20 iyi tanımlanmış bir davranış var mı?
Genellikle, formun kendiliğinden başlatılması, başlatma işlemi tamamlanmadan önce değerinin belirsiz olması T x = x;
nedeniyle tanımlanmamış bir davranışa sahiptir . Belirsiz değerlerin değerlendirilmesi genellikle tanımlanmamış davranışa ( [basic.indent] / 2 ) neden olur , ancak [basic.indent] /2.3'te belirsiz bir değere sahip bir değişkenten doğrudan bir değişkenin başlatılmasına neden olan belirli bir istisna vardır (belirsiz bir değerle başlatmaya neden olur) ).x
unsigned char
unsigned char
Bu tek başına tanımlanmamış davranışa neden olmaz, ancak T
imzasız dar karakter türleri olmayan diğer türler için veya std::byte
ör int x = x;
. C ++ 17 ve öncesinde de uygulanan bu düşünceler, alt kısımdaki bağlantılı sorulara da bakınız.
Bununla birlikte, unsigned char x = x;
mevcut taslak [basic.lifetime] / 7 diyor ki:
Benzer şekilde, bir nesnenin ömrü başlamadan önce [...] değerine bağlı olmayan glvalue özelliklerini kullanmak iyi tanımlanmıştır. Program şu durumlarda tanımsız bir davranışa sahiptir:
glvalue nesneye erişmek için kullanılır veya
[...]
Bu x
, örnekteki değerin sadece ömrü boyunca kullanılabileceği anlamına gelir .
[basic.lifetime] / 1 diyor ki:
[...]
T tipi bir nesnenin ömrü şu durumlarda başlar:
- [...] ve
- başlatma (varsa) tamamlandı (boş başlatma dahil) ([dcl.init]),
[...]
Böylece x
ömrü sadece başlatma tamamlandıktan sonra başlar. Ancak alıntı yapılan örneğin x
değeri, x
başlatma işlemi tamamlanmadan önce kullanılır . Bu nedenle, kullanım tanımsız bir davranışa sahiptir.
Analizim doğru mu ve eğer öyleyse, başlatma öncesi benzer kullanım durumlarını etkiler mi?
int x = (x = 1);
söyleyebildiğim kadarıyla, C ++ 17 ve öncesinde de iyi tanımlanmıştı?
C ++ 17'de (son taslak) yaşamın başlaması için ikinci şartın farklı olduğunu unutmayın :
- nesnenin boş olmayan başlatma işlemi varsa, başlatma işlemi tamamlanmıştır,
Yana x
C ++ 17'nin tanım olarak anlamsız başlatma olurdu yukarıda ve verilen örneklerde başlatıcısı erişildiğinde (ancak mevcut taslak bir), yaşam süresi zaten her iki örnekte de bir tanımsız davranış orada başlamış olur nedeniyle x
C ++ 17 ömrü .
C ++ 17'den önceki ifadeler yine farklıdır, ancak aynı sonuçla.
Soru, örneğin aşağıdaki sorularda yer alan belirsiz değerleri kullanırken tanımlanmamış davranışlarla ilgili değildir:
int x ^= x;
sözdizimsel olarak iyi biçimlendirilmemiş. (Yani Ya ilklendiricili bir değişken tanımı olabilir int x = x;
o UB olsa,) ya da bir yada atama onermesinin (yani x ^= x;
eğer olsa UB olduğunu x
tiptedir int
, varsayılan-başlatıldı ve önceden atandı). Bu ikisini bir araya getiremezsiniz.