我查看了一系列有关序列点的问题,并且一直没有弄清楚如果f修改x , x*f(x)的评估顺序是否有保证,而f(x)*x 。 考虑这个代码: #include <iostream> int fx(int &x) { x = x + 1; return x; } int f1(int &x) { return fx(x)*x; // Line A } int f2(int &x) { return x*fx(x); // Line B } int main(void) { int a = 6, b = 6; std::cout << f1(a) << " " […]
我曾经认为在C99中,即使函数f和g的副作用受到干扰,尽pipeexpression式f() + g()不包含序列点,但f和g将包含一些,所以行为会未指定:f()将在g()之前调用,或者在f()之前调用g()。 我不再那么肯定。 如果编译器内联函数(编译器可能决定执行哪个函数(即使这些函数没有声明为inline函数),然后重新排列指令呢? 可能有人得到上述两个不同的结果吗? 换句话说,这是不确定的行为? 这不是因为我打算写这样的东西,这是在静态分析器中为这样的陈述select最好的标签。
我偶然发现了这个代码,用于交换两个整数而不使用临时variables或使用按位运算符。 int main(){ int a=2,b=3; printf("a=%d,b=%d",a,b); a=(a+b)-(b=a); printf("\na=%d,b=%d",a,b); return 0; } 但是我认为这个代码在交换语句a = (a+b) – (b=a);有未定义的行为a = (a+b) – (b=a); 因为它不包含任何序列点来确定评估的顺序。 我的问题是: 这是一个可接受的解决scheme交换两个整数?
对不起再次打开这个话题,但想到这个话题本身已经开始给我一个未定义的行为。 想要进入明确的行为区域。 特定 int i = 0; int v[10]; i = ++i; //Expr1 i = i++; //Expr2 ++ ++i; //Expr3 i = v[i++]; //Expr4 我想到了上面的expression式(按此顺序) operator=(i, operator++(i)) ; //Expr1 equivalent operator=(i, operator++(i, 0)) ; //Expr2 equivalent operator++(operator++(i)) ; //Expr3 equivalent operator=(i, operator[](operator++(i, 0)); //Expr4 equivalent 现在来到这里的行为是从C ++ 0x重要的引号。 “对expression式(或子expression式)的评估通常包括值计算(包括确定左值评估对象的身份和获取先前赋值给对象进行右值评估的值)以及副作用的启动“。 $ 1.9 / 15-“如果对标量对象的副作用不是相对于同一个标量对象的另一个副作用或使用相同标量对象的值进行值计算,那么行为是未定义的。 [注:与不同参数expression式相关的值计算和副作用是不确定的。 – […]
请考虑以下主题的续篇: 以前的安装 未定义的行为和顺序点 让我们重温一下这个有趣而复杂的expression(斜体字是从上面的话题*微笑*中获得的): i += ++i; 我们说这调用了未定义的行为。 我假设说这个时候,我们隐含地认为i types是内置types之一。 如果i的types是用户定义的types呢? 说它的types是在这篇文章后面定义的Index (见下文)。 它会调用未定义的行为吗? 如果是,为什么? 这不等于写i.operator+=(i.operator++()); 甚至在句法上更简单i.add(i.inc()); ? 或者,他们是否也调用未定义的行为? 如果不是,为什么不呢? 毕竟,对象i在连续的序列点之间被修改两次 。 请回想一下经验法则: expression式只能在连续的“序列点之间修改一个对象的值 ,如果i += ++i是一个expression式,那么它必须调用未定义的行为i.operator+=(i.operator++());和i.add(i.inc());还必须调用undefined-行为似乎是不真实的(据我所知) 或者, i += ++i不是一个expression式开始? 如果是这样,那么它是什么, expression的定义是什么? 如果它是一个expression式,并且同时它的行为也是明确定义的,那么它意味着与某个expression式相关联的序列点的数量在某种程度上取决于expression式中涉及的操作数的types 。 我是否正确(甚至部分)? 顺便说一下,这个expression呢? //Consider two cases: //1. If a is an array of a built-in type //2. If a is user-defined […]
什么是“序列点”? 未定义的行为和顺序点之间的关系是什么? 我经常使用有趣和令人费解的expression式,如a[++i] = i; ,让自己感觉更好。 为什么我应该停止使用它们? 如果您已经阅读过这些内容,请务必访问后续问题重新加载未定义的行为和顺序点 。 (注意:这是一个Stack Overflow的C ++常见问题解答的入口,如果你想批评在这个表单中提供FAQ的想法,那么在这个开始所有这些的meta上的贴子将是这个地方的答案。那个问题在C ++聊天室中进行监控,常见问题解决scheme首先出现,所以你的答案很可能会被那些提出这个想法的人阅读)。