มีคุณสมบัติที่เป็นระเบียบมากของนิพจน์คงที่ใน 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
แต่ให้ ตามเอกสารf
consteval
:
consteval - ระบุว่าฟังก์ชั่นเป็นฟังก์ชั่นทันทีนั่นคือการเรียกใช้ฟังก์ชั่นทุกครั้งจะต้องสร้างค่าคงที่เวลารวบรวม
ฉันคาดหวังว่าโปรแกรมดังกล่าวจะทำให้เกิดข้อผิดพลาดในการรวบรวมอีกครั้ง แต่โปรแกรมจะรวบรวมและทำงานกับ UB แทนแทน
ทำไมถึงเป็นอย่างนั้น?
UPD: ผู้แสดงความคิดเห็นแนะนำว่านี่เป็นข้อผิดพลาดคอมไพเลอร์ ฉันรายงานแล้ว: https://bugs.llvm.org/show_bug.cgi?id=43714
in call to 'f(3)'
- มันแปลก ๆ! อดีต หากคุณใส่เสียงดังกราวเตือนเกี่ยวกับf(123)
in call to 'f(119)'