我以前认为在C99中,即使函数的副作用f和g干扰,虽然表达式f() + g()不包含序列点,f并且g会包含一些,所以行为将是未指定的:要么f()之前调用f()之前的g()或g().
我不再那么肯定了.如果编译器内联函数(即使未声明函数,编译器可能决定这样做inline)然后重新排序指令,该怎么办?可能有人得到上述两种不同的结果吗?换句话说,这是未定义的行为吗?
这不是因为我打算写这种东西,而是在静态分析器中为这样的语句选择最佳标签.
c c99 undefined-behavior sequence-points unspecified-behavior
假设我的函数foo(x, y, z)在其参数的所有排列中都是不变的.我也有一个迭代it,使得迭代器it,it + 1并且it + 2可以解除引用.
写得好吗
... = foo(*it++, *it++, *it++); // (1)
Run Code Online (Sandbox Code Playgroud)
代替
... = foo(*it, *(it + 1), *(it + 2)); // (2)
Run Code Online (Sandbox Code Playgroud)
?
据我所知,技术上它是正确的,因为C++ 17由于(引用cppreference.com并考虑到它it可以是一个原始指针)
15)在函数调用中,关于任何其他参数的值计算和副作用,每个参数的初始化的值计算和副作用是不确定地排序的.
函数参数的评估顺序没有定义,但对于foo()顺序无关紧要.
但这是一种可接受的编码风格吗?一方面,它(1)非常对称,暗示foo具有这样的不变性,(2)看起来有些难看.另一方面,(1)立即提出有关其正确性的问题 - 阅读代码的人应该检查描述或定义foo以验证呼叫的正确性.
如果身体foo()很小并且函数定义中的不变性很明显,你会接受(1)吗?
(可能这个问题是基于意见的.但我不禁要问它.)