C++ 可以在编译时拒绝保证UB吗?
考虑一下这个计划:C++ 可以在编译时拒绝保证UB吗?,c++,c,language-lawyer,undefined-behavior,C++,C,Language Lawyer,Undefined Behavior,考虑一下这个计划: #include <stdio.h> int main(void) { int x; while ( 1 == scanf("%d", &x) ) printf("%c\n", "hello"[x]); } int main(void) { printf("hello\n"); "hello"[6]; } 对该程序的任何调用都会导致未定义的行为,并且由于这可能会导致时间旅行,因此该程序在任何调用上的整
#include <stdio.h>
int main(void)
{
int x;
while ( 1 == scanf("%d", &x) )
printf("%c\n", "hello"[x]);
}
int main(void)
{
printf("hello\n");
"hello"[6];
}
对该程序的任何调用都会导致未定义的行为,并且由于这可能会导致时间旅行,因此该程序在任何调用上的整个行为都是未定义的。因此,编译器能否拒绝该程序而不生成可执行文件?(我们可以说UB回到了编译阶段!)
因此,编译器能否拒绝该程序而不生成可执行文件
对。未定义行为的定义为:
本国际标准不要求的行为
[注:当本国际标准省略任何明确的行为定义,或当程序使用错误的构造或错误的数据时,可能会出现未定义的行为。允许的未定义行为
范围从完全忽略具有不可预测结果的情况,到在翻译或程序执行过程中以环境特有的文件化方式(无论是否发出诊断消息),到终止翻译或执行(发出诊断消息).许多错误的程序结构不会产生未定义的行为;它们需要被诊断。-结束注释]
补充乔纳森的回答 第二个程序调用未定义的行为,编译器有权停止转换,因为未定义的行为没有边界(c11,3.4.3p1) 第一个程序可以调用未定义的行为,但编译器无法停止转换,因为并非所有执行路径都会产生未定义的行为 在这方面,委员会说: 此外,如果给定程序的每一次可能的执行都会导致未定义的行为,那么给定程序就不是严格一致的。 一致性实现不能仅仅因为程序的某些可能执行会导致未定义的行为而无法转换严格一致性程序
@扎菲:
“hello”[5]
是“\0”
,“hello”[6]
是越界的。@Jarod42哦,是的,对不起:)对未定义行为的可靠而可靠的检测是一个无法执行或无法确定的问题……是的,这方面的完美例子是constepr
,在这些情况下,我们可以看到clang
和gcc
reject代码>,但这是UB,不是违反约束。不过,在我看来,你的例子有点不同。