使用std::cout对参数求值的顺序
Order of evaluation of arguments using std::cout
大家好,我今天偶然发现了这段代码,我很困惑到底发生了什么,更具体的是按什么顺序:
代码:
#include <iostream>
bool foo(double & m)
{
m = 1.0;
return true;
}
int main()
{
double test = 0.0;
std::cout << "Value of test is : t" << test << "tReturn value of function is : " << foo(test) << "tValue of test : " << test << std::endl;
return 0;
}
输出为:
Value of test is : 1 Return value of function is : 1 Value of test : 0
看到这一点,我会假设在调用函数之前会打印出最正确的参数。所以这是从右到左的评价??不过,在调试过程中,函数似乎是在输出之前调用的,这正是我所期望的。我正在使用Win7和MSVS2010。感谢您的帮助!
表达式中元素的求值顺序是未指定的(除了一些非常特殊的情况,例如&&
和||
运算符以及三元运算符,它们引入了序列点(;因此,不能保证test
将在foo(test)
(修改它(之前或之后被评估。
如果您的代码依赖于特定的求值顺序,那么获得它的最简单方法是将表达式拆分为几个单独的语句。
这个问题的答案在C++17中发生了变化。
重载运算符的评估现在按照与内置运算符相同的方式排序(C++17[over.match.oper]/2(。
此外,<<
、>>
和下标运算符现在将左操作数排序在右操作数之前,并且函数调用的后缀表达式在参数的求值之前排序。
(其他二进制运算符保留其先前的排序,例如+
仍然未排序(。
因此,问题中的代码现在必须输出Value of test is : 0 Return value of function is : 1 Value of test : 1
。但"不要这样做"的建议仍然是合理的,因为每个人都需要一段时间才能更新到C++17。
未指定评估顺序。它不是从左到右,从右到左,或者其他任何东西。
不要这样做。
未指定评估顺序,请参阅http://en.wikipedia.org/wiki/Sequence_point
这与操作员的示例+示例相同:
考虑两个函数
f()
和g()
。在C和C++中,+
运算符不与序列点相关联,因此在表达式f()+g()
中,可能首先执行f()
或g()
。
c++引用很好地解释了为什么永远不应该这样做(导致UB或未定义的行为(https://en.cppreference.com/w/cpp/language/operator_incdec
#include <iostream>
int main()
{
int n1 = 1;
int n2 = ++n1;
int n3 = ++ ++n1;
int n4 = n1++;
// int n5 = n1++ ++; // error
// int n6 = n1 + ++n1; // undefined behavior
std::cout << "n1 = " << n1 << 'n'
<< "n2 = " << n2 << 'n'
<< "n3 = " << n3 << 'n'
<< "n4 = " << n4 << 'n';
}
票据
由于所涉及的副作用,内置增量和减量必须小心使用运算符,以避免由于违反排序规则。
在与排序规则相关的部分中,您可以阅读以下内容:
未定义的行为:
1( 如果标量对象的副作用相对于同一标量对象的另一个副作用是未排序的,则行为是未定义的。
i = ++i + 2; // undefined behavior until C++11
i = i++ + 2; // undefined behavior until C++17
f(i = -2, i = -2); // undefined behavior until C++17
f(++i, ++i); // undefined behavior until C++17, unspecified after C++17
i = ++i + i++; // undefined behavior
2( 如果标量对象上的副作用相对于使用同一标量对象的值的值计算是未排序的,则行为是未定义的。
cout << i << i++; // undefined behavior until C++17
a[i] = i++; // undefined behavior until C++17
n = ++i + i; // undefined behavior
- 遍历顺序由 std::文件系统directory_iterator给出
- std::remove_reference_t<std::remove_cv_t<T>>顺序重要吗?
- 标记为 std::memory_order_seq_cst 的单个原子操作是否会在所有位置触发顺序一致性?
- std::bind() 参数列表中函子的执行顺序(可能与函数参数的求值顺序无关)
- 基于 std::vector <string>的内容动态设置顺序的模式
- std::unique_ptr析构函数顺序
- 如何实现对参数顺序不可知的std::same_as的广义形式(即对于两个以上的类型参数)
- 基于 C++ 范围的 std::vector 迭代的顺序
- GNUMakefile 和 gcc:解决冲突"-std=c++"需求的顺序
- 将字符指针按顺序存储在 map 中 std::map<char*, int> mymap。将其存储为字符或字符串不是一个选项
- std::apply是否为评估顺序提供保证
- 为什么具有顺序一致性的 std::原子存储使用 XCHG
- 更改 std::set 作为成员属性的顺序
- `sTD :: sample()的输出序列是否遵循输入序列的顺序
- C++ 为什么 std::async 比顺序执行慢
- std::mutex顺序一致吗
- 如何使用 std::shuffle 以随机顺序对具有唯一指针的向量进行洗牌
- 以std::字符串作为关键字,按字典顺序对一个无序映射进行排序
- 调用std::nth_element后第n个元素之前的元素顺序
- 插入顺序std::map