Kendi başlatıcısında değişken kullanımı


22

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) ).xunsigned charunsigned char

Bu tek başına tanımlanmamış davranışa neden olmaz, ancak Timzası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 xdeğeri, xbaş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 xC ++ 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 xC ++ 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:


@LanguageLawyer Doğru olduğumdan emin değilim, özellikle de henüz kimse cevap vermediğinde. Diğerleri burada benimle aynı fikirde olacaklarsa, daha sonra dosya açabilirim (ya da belki bir başkası benden önce gelir), ama emin olmadığım sorunları dosyalamak istemiyorum.
Ceviz

@LanguageLawyer: Çalışma kağıdı açık bir şekilde yanlış bir şey söylüyorsa, bir editoryal sorun olamaz.
Davis Herring

1
Kelime P1358 ile değiştirilir .
xskxzr

1
@xskxzr Doğru ve bu arada LanguageLawyer , niyetin açıklığa kavuşturulması için CWG'ye iletilmiş gibi bir editoryal sorun da açtı .
ceviz

1
@ clockw0rk 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 xtiptedir int, varsayılan-başlatıldı ve önceden atandı). Bu ikisini bir araya getiremezsiniz.
Ceviz

Yanıtlar:


8

Bu, editoryal bir sorun olarak açıldı . (Dahili) tartışma için CWG'ye iletildi. Yaklaşık 24 saat sonra sorunu ileten kişi, bunun UB olduğunu açıkça belirtmek için örneği değiştiren bir çekme isteği oluşturdu :

Burada, ikinci \ tcode {x} öğesinin başlatılması tanımlanmamış bir davranışa sahiptir, çünkü başlatıcı ikinci \ tcode {x} 'ye ömür boyu \ iref {basic.life} dışında erişir.

O PR o zamandan beri eklendi ve sorun kapatıldı. Dolayısıyla, açık yorumlamanın (ömrü başlamayan bir nesneye erişim nedeniyle UB) amaçlanan yorum olduğu açıktır. Komitenin amacı görünür olan bu yapılar işlevsel olmayan hale getirmek için, ve standardın olmayan normatif metin bu yansıtacak şekilde güncellendi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.