在同一语句中调用的执行 IO 的函数:未定义或未指定
IO-performing functions called in same statement: Undefined or unspecified?
我开始从C++入门(第5版(中学习C++。 在完成有关表达式的章节时,我想出了一个示例程序,让我想知道:
int f1()
{
cout << "f1n";
return 1;
}
int f2()
{
cout << "f2n";
return 2;
}
int main() {
int i = f1() + f2();
return 0;
}
我不确定该程序是调用未定义的行为还是仅调用未指定的行为。 我知道调用函数f1
和f2
的顺序是未指定的。 每个函数都写入标准输出作为副作用,因此充其量是未指定行的打印顺序。 在最坏的情况下,这会调用未定义的行为。
我知道答案就在C++标准中的某个地方,但对于我目前的理解水平来说,这是相当技术性的。 更温和的解释将不胜感激。
未指定的行为
程序的行为因实现而异,并且不需要符合实现来记录每个行为的效果。例如,计算顺序、相同的字符串文本是否不同、数组分配开销量等。每个未指定的行为都会导致一组有效结果之一。
评估顺序
这里没有从左到右或从右到左C++评估的概念。这不要与运算符的从左到右和从右到左的结合性混淆:表达式 f1(( + f2(( + f3(( 由于运算符 + 的从左到右结合性,表达式 f1(( + f2((( + f3(( 被解析为 (f1(( + f2(((,但对 f3 的函数调用可以在运行时首先、最后或在 f1(( 或 f2(( 之间计算。
如果顺序很重要,你这样做
int a = f1();
int b = f2();
int i = a + b;
如果顺序不重要,那么代码就完全没问题了。
"未定义的行为"的话题在网站上相当令人讨厌。在相当长的一段时间里,有很多问题问"这是未定义的行为吗?",而回答者则争先恐后地说"是",而事实并非如此。我相信你想的是这样的情况:
对运算符操作数的值计算进行排序 在计算运算符结果的值之前。如果一面 对标量对象的影响相对于另一个对象是未排序的 对同一标量对象的副作用或使用 同一标量对象的值,并且它们不是潜在的 并发 (1.10(,行为未定义。
[ 示例:
void f(int, int); void g(int i, int* v) { i = v[i++]; // the behavior is undefined i = 7, i++, i++; // i becomes 9 i = i++ + 1; // the behavior is undefined i = i + 1; // the value of i is incremented f(i = -1, i = -1); // the behavior is undefined }
— 结束示例 ]
修改对象和调用库 I/O 函数都是副作用。除此之外,没有任何关系暗示您的示例具有未定义的行为。
我遇到的另一个问题是回答者,他们宁愿抛弃一堆听起来不错的标准语言,这些标准语言比人类友好的版本更难解析。结果,人们往往会错过更大的图景。下面是一个示例:
§1.9/15 对于每个函数调用 F,对于每个求值 A 发生在 F 和每个未发生的评估 B 中 在 F 中,但在同一线程上作为同一线程的一部分进行评估 信号处理程序(如果有(,A 在 B 之前排序,或者 B 在 在 A 之前排序。
翻译:如果A和B不会被测序,那么它们就会被不确定地测序。根据定义,不确定的顺序意味着它们可以以任何顺序出现,但不能重叠。
此外,在不精确的术语中,+
运算符的操作数是未排序的。因此+
并不代表"序列点"。因此,f1()
和f2()
是不确定的排序,您可以推断这是未指定的行为。
DR:忘记标准,专注于学习语言。你太纠结于细节,你忽视了大局,混淆了事情。这是一篇关于这个主题的人性化论文
- 2个模板化类的非模板友元函数未定义引用错误
- C++:在共享对象中调用抽象基类构造函数/未定义的符号
- 获取线函数未定义错误。无法在字符串中保存可验证的内容
- 链表复制构造函数 |未定义的行为
- 尝试使用 std::函数(未定义的符号)声明模板化类状态时出现链接错误
- 专用纯虚拟模板函数(未定义引用)的另一个问题
- 可视化C++ strtoull 函数未定义
- 绑定C++中的C函数(未定义的引用)
- 函数未定义引用c++
- C++构造函数未定义的引用
- 在同一语句中调用的执行 IO 的函数:未定义或未指定
- 在参数中接受 2 个类的友元函数 - 未定义'Class'
- c++ CreateWindow()函数未定义
- 使用c++中的haskell函数:未定义引用错误
- c++模板变量函数未定义引用
- OpenGL函数未定义glow
- C/ c++未使用的内联函数未定义的引用
- 调用从不兼容类型强制转换的零数据结构的成员函数-未定义
- Cocos2d-x Box2D CContactListener构造函数未定义
- 包括Boost网络库使Windows.h函数未定义