C ++ 20'de daha sonraki bir çalışma zamanı kararına dayanan farklı örtük nesneler olabilir mi?


11

Bu soru, P0593'ün en son C ++ 20 taslağına eklenmesini ifade eder .

İşte benim örnek:

#include <cstdlib>
#include <cstdio>

void foo(void *p)
{
    if ( std::getchar() == 'i' )
    {
        *(int *)p = 2;
        std::printf("%d\n", *(int *)p);
    }
    else
    {
        *(float *)p = 2;
        std::printf("%f\n", *(float *)p);
    }
}

int main()
{
    void *a = std::malloc( sizeof(int) + sizeof(float) );
    if ( !a ) return EXIT_FAILURE;

    foo(a);
    // foo(a);    [2]
}

Bu kod, en son taslak kapsamındaki tüm girdiler için iyi tanımlanmış mı?

P0593'te ifade edilen gerekçe [2], iki kullanıcı giriş öğesi farklıysa , rahatsız etmenin katı takma ad ihlali nedeniyle tanımlanamayan davranışlara yol açacağını oldukça açık bir şekilde ortaya koymaktadır . Örtük nesne yaratmanın şu noktada sadece bir kez olması gerekiyordu malloc; içindeki atama ifadesi tarafından tetiklenmez foo.

Programın herhangi bir gerçek çalıştırması için, programı iyi tanımlanmış yapacak, belirtilmemiş örtük nesneler grubunun bir üyesi vardır. Ancak, [intro.object] / 10'da belirtilen örtük nesne oluşturma seçiminin gerçekleştiğinde yapılması gerekip gerekmediği bana açık değil malloc; veya kararın "zaman yolculuğu" yapıp yapamayacağı.

Aynı sorun, ikili bir bloğu bir arabelleğe okuyan ve daha sonra ona nasıl erişileceğine ilişkin bir çalışma zamanı kararı veren bir program için de ortaya çıkabilir (örn.

Yanıtlar:


9

Örtük nesne yaratmanın şu noktada sadece bir kez olması gerekiyordu malloc; içindeki atama ifadesi tarafından tetiklenmez foo.

Alakalı değil. Önemli olan hangi nesnenin yaratıldığıdır. Standart, oluşturulan nesnenin iyi tanımlanmış koda UB olabilecek bir şey yapan bir nesne olduğunu söylüyor:

bu işlem örtülü olarak, belirtilen depolama alanında sıfır veya daha fazla örtülü ömür boyu tür ([basic.types]) nesnenin ömrünü oluşturur ve başlatırsa, program tanımlanmış davranışa neden olur.

Davranış sonuçta statik analiz değil, çalışma zamanı yürütülmesine dayanır. Bu nedenle, programın yürütülmesini, yalnızca davranışın tanımlanmayacağı bir durumda karşılaşana kadar izlemeniz gerekir; ancak söz konusu işlem sırasında söz konusu depolama alanında bir tür nesne oluşturulmuşsa tanımlanır.

Yani yaratılışın yeri her zaman "işlem" dir, fakat yaratılan şeyin belirlenmesi hafızanın çalışma zamanında nasıl kullanıldığına bağlıdır (yani: davranış).


2
Açıkça söylemek gerekirse, kodumun iyi tanımlandığını mı söylüyorsunuz?
MM

2
@MM: Doğru.
Nicol Bolas
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.