c++ - 为什么这些示例中的一个是未定义行为而另一个不是?

标签 c++ undefined-behavior

this 的评论回复声明不应使用以下代码,因为它表现出未定义的行为:

int old = (std::cin >> old, old);

类似的代码也被大大鄙视了here ,特别是表现出未定义的行为。

另一方面,this高度赞成的回复建议将以下代码作为逗号运算符的有用性示例:

while (cin >> str, str != "STOP") {
    //process str
}

我假设如果这段代码表现出未定义的行为,它就不会被投票。

问题:如果第一个代码是未定义的行为(大概是因为使用了从cin读取的结果而不检查后者的状态),那么为什么是第二个代码好吗?

编辑:第一个例子的评论部分回答了这个问题。第二个示例没有显示的是 strstd::string 的一个实例,因此被初始化。因此,不存在未定义的行为。

最佳答案

声明 int old = (std::cin >> old, old); 自 C++11 以来定义明确 假设读取非空白字符。这是因为如果 std::cin 在这种情况下失败,则 old 将设置为零。 表达式分隔符 运算符 , 的使用也是合法的,因为它对表达式 std::cin >> oldold< 进行排序。如果没有反击非空白字符,则 old 仍未被 std::cin >> old 更改,并且代码的行为未定义。

假设 str 是一个 std::string 类型,(cin >> str, str != "STOP") 总是 定义明确。如果 cin >> str 失败,则保留 str 的初始(可能是默认构造的)值,并再次 , 对表达式进行排序。

关于c++ - 为什么这些示例中的一个是未定义行为而另一个不是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57848792/

相关文章:

c++ - 我如何才能真正使用std::chrono类型而不冒溢出和未定义行为的风险?

c++ - 当不使用指针来跟踪当前节点时,为什么树遍历会导致未定义的行为?

c++ - 自定义分配器如何知道指针是否指向数组?

c++ - 重载运算符的返回值分段失败

带有键的 C++11 映射定义了一个值范围

c++ - 系统调用成本

c++ - 什么时候在空实例上调用成员函数会导致 C++11 中的未定义行为?

c - 这是 C 中的未定义行为吗?如果不能逻辑地预测输出

c++ - 为什么我的覆盖方法没有被调用?

c++ - Clang 5.0 和 UBsan 的指针加法和整数溢出?