Sıkılaştırma işlevi neden tanımlanmamış davranışa izin veriyor?


16

C ++ 'da sabit ifadelerin çok düzgün bir özelliği vardır: değerlendirmelerinin tanımlanmamış davranışı olamaz ( 7.7.4.7 ):

E ifadesi, soyut makinenin kurallarına ([intro.execution]) uygun olarak e değerlendirmesi aşağıdakilerden birini değerlendirmediği sürece, temel sabit bir ifadedir:

  • ...

  • bu belgenin [intro] ila [cpp] 'de belirtildiği gibi tanımlanmamış davranışa sahip bir işlem [Not: örneğin işaretli tamsayı taşması ([expr.prop]), belirli işaretçi aritmetiği ([expr.add]), sıfıra bölme veya belirli vardiya işlemleri - son not];

Değerini depolamak için çalışırken 13!bir de constexpr intgerçekten iyi bir derleme hata verir :

constexpr int f(int n) 
{
    int r = n--;
    for (; n > 1; --n) r *= n;
    return r;
}

int main() 
{
    constexpr int x = f(13);
    return x;
}

Çıktı:

9:19: error: constexpr variable 'x' must be initialized by a constant expression
    constexpr int x = f(13);
                  ^   ~~~~~
4:26: note: value 3113510400 is outside the range of representable values of type 'int'
    for (; n > 1; --n) r *= n;
                         ^
9:23: note: in call to 'f(3)'
    constexpr int x = f(13);
                      ^
1 error generated.

(BTW hata neden f (13) 'e bir çağrı iken "f (3)" çağrısını söylüyor? ..)

Sonra, ben kaldırmak constexprgelen x, ancak yapmak fbir consteval. Dokümanlara göre :

consteval - bir işlevin anlık bir işlev olduğunu, yani işleve yapılan her çağrının bir derleme zamanı sabiti üretmesi gerektiğini belirtir

Böyle bir programın tekrar derleme hatasına neden olmasını bekliyorum. Ancak bunun yerine, program derlenir ve UB ile çalışır .

Neden?

UPD: Yorum yapanlar bunun bir derleyici hatası olduğunu öne sürdüler. Rapor ettim: https://bugs.llvm.org/show_bug.cgi?id=43714


2
in call to 'f(3)'- bu tuhaf! Ör. Eğer f(123)clang koyarsanız hakkında uyarır in call to 'f(119)'.
KamilCuk

Bence bu sadece bir hata. Standart, "acil bir çağrının sürekli bir ifade olacağı" açıktır. Bununla birlikte, daha karmaşık bir şey olması da mümkündür (yani, belki de bu gereksinim ortadan kalkacak ve Clang yeni davranışı uygulamaktadır).
Brian

3
Derleyici hatası. Burada görecek bir şey yok, ilerle.
TC

1
@JesperJuhl Tamamlandı.
Mikhail

4
@StoryTeller Tamsayılar ikisinin tamamlayıcısıdır, ancak taşma hala tanımsızdır.
Barry

Yanıtlar:


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.