什么是"序列点"?
未定义的行为和序列点之间的关系是什么?
我经常使用有趣和复杂的表达方式a[++i] = i;,让自己感觉更好.我为什么要停止使用它们?
如果您已阅读此内容,请务必访问后续问题重新加载未定义的行为和序列点.
(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)
大家好我今天偶然发现了这段代码,我对于究竟发生了什么以及更具体的顺序感到困惑:
代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Value of test is : 1 Return value of function is : 1 Value of test : 0
Run Code Online (Sandbox Code Playgroud)
看到这一点,我会假设在调用函数之前打印出最正确的参数.那么这是对的评价吗?在调试期间,虽然似乎在输出之前调用该函数,这是我所期望的.我正在使用Win7和MSVS 2010.任何帮助表示赞赏!
我在这里有一个C++学习演示:
char c = 'M';
short s = 10;
long l = 1002;
char * cptr = &c;
short * sptr = &s;
long * lptr = &l;
cout << "cptr:\t" << static_cast<void*>(cptr) << '\n';
cout << "cptr++:\t" << static_cast<void*>(++cptr) << '\n';
cout << "sptr:\t" << sptr << '\n';
cout << "sptr++:\t" << ++sptr << '\n';
cout << "lptr:\t" << lptr << '\n';
cout << "lptr++:\t" << ++lptr << '\n';
cout << c << '\t' << static_cast<void*>(cptr) << '\t' << …Run Code Online (Sandbox Code Playgroud) 可能重复:
未定义的行为和序列点
我不确定这是否是一个gcc bug,所以我会问:
unsigned int n = 0;
std::cout << n++ << n << ++n;
Run Code Online (Sandbox Code Playgroud)
gcc给出了非常奇怪的结果:AFAICT是不可能的"122".因为<<是左关联的,它应该是相同的:
operator<<(operator<<(operator<<(std::cout, n++), n), ++n)
Run Code Online (Sandbox Code Playgroud)
并且因为在评估参数之前和之后存在一个序列点,所以n在两个序列点之间永远不会被修改两次(甚至访问) - 因此它不应该是未定义的行为,只是未指定的评估顺序.
所以AFAICT的有效结果将是:111 012 002 101
没有别的