ทำไมฟังก์ชั่น consteval ถึงมีพฤติกรรมที่ไม่ได้กำหนดไว้?


16

มีคุณสมบัติที่เป็นระเบียบมากของนิพจน์คงที่ใน C ++: การประเมินของพวกเขาไม่สามารถมีพฤติกรรมที่ไม่ได้กำหนด ( 7.7.4.7 ):

นิพจน์ e เป็นนิพจน์ค่าคงที่หลักเว้นแต่ว่าการประเมิน e ตามกฎของเครื่องนามธรรม ([intro.execution]) จะประเมินข้อใดข้อหนึ่งต่อไปนี้:

  • ...

  • การดำเนินการที่จะมีพฤติกรรมที่ไม่ได้กำหนดตามที่ระบุไว้ใน [บทนำ] ถึง [cpp] ของเอกสารนี้ [หมายเหตุ: รวมถึงตัวอย่างเช่นจำนวนเต็มล้นลงนาม ([expr.prop]) บางตัวชี้ทางคณิตศาสตร์ ([expr.add]) การหารด้วยศูนย์หรือการเลื่อนบางอย่าง - หมายเหตุท้าย];

การพยายามเก็บค่าของ13!ในข้อผิดพลาดconstexpr intจริงทำให้คอมไพล์คอมไพล์ดี :

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;
}

เอาท์พุท:

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 เหตุใดข้อผิดพลาดจึงพูดว่า "call to 'f (3)'" ในขณะที่โทรไปยัง f (13)? .. )

แล้วฉันลบconstexprจากxแต่ให้ ตามเอกสารfconsteval :

consteval - ระบุว่าฟังก์ชั่นเป็นฟังก์ชั่นทันทีนั่นคือการเรียกใช้ฟังก์ชั่นทุกครั้งจะต้องสร้างค่าคงที่เวลารวบรวม

ฉันคาดหวังว่าโปรแกรมดังกล่าวจะทำให้เกิดข้อผิดพลาดในการรวบรวมอีกครั้ง แต่โปรแกรมจะรวบรวมและทำงานกับ UB แทนแทน

ทำไมถึงเป็นอย่างนั้น?

UPD: ผู้แสดงความคิดเห็นแนะนำว่านี่เป็นข้อผิดพลาดคอมไพเลอร์ ฉันรายงานแล้ว: https://bugs.llvm.org/show_bug.cgi?id=43714


2
in call to 'f(3)'- มันแปลก ๆ! อดีต หากคุณใส่เสียงดังกราวเตือนเกี่ยวกับf(123) in call to 'f(119)'
KamilCuk

ฉันคิดว่านี่เป็นเพียงข้อผิดพลาด มาตรฐานมีความชัดเจนว่า "การร้องขอทันทีจะเป็นการแสดงออกที่คงที่" อย่างไรก็ตามอาจเป็นไปได้ว่ามีบางอย่างที่ซับซ้อนเกิดขึ้น (เช่นอาจเป็นไปได้ว่าข้อกำหนดนั้นจะถูกลบออกและเสียงดังกราวกำลังใช้พฤติกรรมใหม่)
Brian

3
ข้อผิดพลาดของคอมไพเลอร์ ไม่มีอะไรให้ดูที่นี่ย้ายไปตาม
TC

1
@JesperJuhl เรียบร้อยแล้ว
Mikhail

4
@StoryTeller Integers เป็นส่วนเติมเต็มของสอง แต่ล้นยังไม่ได้กำหนด
Barry

คำตอบ:


2

นี่เป็นข้อผิดพลาดของคอมไพเลอร์ หรือเพื่อให้แม่นยำยิ่งขึ้นนี่คือคุณลักษณะ "underimplemented" (ดูความคิดเห็นใน bugzilla ):

Yup - ดูเหมือนว่ายังไม่มีการใช้งาน consteval ตาม: https://clang.llvm.org/cxx_status.html

(อาจมีการเพิ่มคำหลัก แต่ไม่ใช่การสนับสนุนการใช้งานจริง)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.