UB何时发生,是否使所有先前订立的合同无效?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (6)

C或C ++语言语义与用户形成一个契约。有些构造对它们的行为没有任何限制,要么是因为在某些情况下没有指定的行为(比如解除引用不指向对象的指针,如空指针),要么显式未定义。在任何一种情况下,都不保证提供以下行为。

但过去怎么样?这些指令定义了行为并生成了输出。我想输出可以被删除,但过去可能已经观察到之前的相互作用。

未定义的行为是否具有先见之明,以至于某些输出不会发生?例如:

std::cout << "hello, world" << std::endl; // with a flush
float f = 1./0.; // UB: cancels previous syscall?

不会在write系统调用(假设Unix)符合这里吗?

那么内存模型呢?可以保证原子对象,互斥体和所有顺序一致的操作上的所有操作都有一个命令(每个操作都与指令流一致,但它们的联合不必是); 如果程序显示未定义的行为,何时应用该保证?

实现是否可以在程序执行的某个时刻使用未定义的行为作为不遵守内存模型要求的借口?换句话说,作为语言语义的合同客户(用户)在哪些点可以期望交付这些要求(在I / O上,在操作命令上)?

澄清:只有完善的计划

(我意识到我可能不会像我想的那样具体。)

一些源代码违反一致性或健全性规则的程序:

  • 违反一个定义规则
  • 没有有效专业化的模板
  • 在不同点绑定到不同名称的模板

被描述为完全无效。编译器可以使用诊断或编译来拒绝这些程序,但在这种情况下,程序的执行没有定义行为。我们称之为“ 先验 UB”。

问题不是关于那些程序,而是关于良好形成的程序,至少在一段时间内可以有一些明确定义的执行。

提问于
用户回答回答于

未定义的行为是否具有先见之明,以至于某些输出不会发生?例如:...不会在write系统调用(假设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;
};

[intro.execution] /7.3中的规定适用:

交互设备的输入和输出动态应以这样一种方式进行,即在程序等待输入之前提示输出实际被传送。构成交互设备的是实现定义的。

因此,不允许程序等待输入非零值,然后才打印出消息Please enter a number:。它必须先打印出消息。因此,从这个意义上讲,UB的范围仅限于在输入足够的输入以确定行为未定义的点之后发生的事件。

扫码关注云+社区

领取腾讯云代金券