cur*_*guy 0 c++ memory-model undefined-behavior language-lawyer
C或C ++语言语义与用户形成矛盾。一些构造对它们的行为没有任何限制,这是由于在某些情况下(例如,取消引用未指向对象的指针,例如空指针)没有指定的行为,或者是通过明确地未定义。在任何一种情况下,都不能保证以下行为。
但是过去呢?这些已定义行为并产生输出的指令。我想可以删除输出,但是以前的交互可能在过去已经观察到。
未定义的行为是否可以预先确定,从而不会产生某些输出?例如:
std::cout << "hello, world" << std::endl; // with a flush
float f = 1./0.; // UB: cancels previous syscall?
Run Code Online (Sandbox Code Playgroud)
不会在这里进行write
syscall(假设是Unix)吗?
现在该内存模型如何?可以保证对原子对象,互斥体以及所有顺序一致的操作的所有操作均具有顺序(每个命令均与指令流一致,但不一定要有并集);如果程序表现出未定义的行为,什么时候适用保证?
在程序执行的某个时刻,实现可以使用未定义的行为作为不遵守内存模型要求的借口吗?换句话说,语言语义(用户)的合同客户可以在何时实现这些要求(在I / O上,在操作顺序上)?
(我意识到我可能没有我想要的那么具体。)
一些其源代码违反一致性或健全性规则的程序:
被描述为完全无效。编译器可以通过诊断拒绝这些程序,也可以对其进行编译,但是在那种情况下,该程序的执行未定义行为。让我们将其称为“ 先验 UB”。
问题不是关于那些程序,而是关于结构良好的程序,这些程序至少可以在一段时间内执行良好的定义。
Bri*_*ian 14
未定义的行为是否可以预先确定,从而不会产生某些输出?例如:...不会在这里进行
write
syscall(假设Unix)吗?
是的,这是符合要求的。参见[intro.execution] / 5:
执行格式正确的程序的合格实现应产生与具有相同程序和相同输入的抽象机相应实例的可能执行之一相同的可观察行为。但是,如果任何这样的执行包含未定义的操作,则本文档对使用该输入执行该程序的实现没有任何要求(甚至不涉及第一个未定义的操作之前的操作)。
由于您的程序包含无条件的 UB,因此该标准对任何程序运行的实现行为都没有要求。
请注意,在UB取决于输入的情况下,例如:
int main()
double x;
std::cout << "Please enter a number: ";
std::cin >> x;
std::cout << "The reciprocal of your number is: " << 1/x << std::endl;
};
Run Code Online (Sandbox Code Playgroud)
[intro.execution] /7.3中的规定适用:
交互式设备的输入和输出动态应该以一种方式进行,即在程序等待输入之前,实际上会发出提示输出。构成交互式设备的是实现定义的。
因此,不允许程序等待输入非零值,然后才输出消息Please enter a number:
。它必须先打印出消息。因此,从这个意义上讲,UB的范围限于在输入了足够多的输入以确定行为未定义之后发生的事件。