cme*_*eub 10 c c++ cross-platform variable-assignment logical-operators
我刚刚学会了这个伟大的模式(实际上来自javascript),我想将它应用到我的c ++代码中.
为了解释模式,假设我将字符串表示为这些的链接列表:
struct link_char;
struct link_char
{
link_char * next;
char code;
};
Run Code Online (Sandbox Code Playgroud)
请注意,任何link_char字符串的最后一个字符始终具有代码== 0.这个属性意味着我可以检查字符串中的值,同时使用&&短路来防止NULL指针访问.
bool equals_hello( const link_char * first_char )
{
const link_char * c = first_char;
return c->code=='h'
&& (c=c->next)->code=='e'
&& (c=c->next)->code=='l'
&& (c=c->next)->code=='l' // if string == "hel", we short-circuit here
&& (c=c->next)->code=='o';
}
Run Code Online (Sandbox Code Playgroud)
我的问题是安全性,而不是可读性.我知道只要&&没有超载,短路就会起作用.但是,赋值操作是否会以正确的顺序发生,还是实现定义?
以上示例明确说明了读/写可能发生的位置,但我也想在可能存在副作用的情况下使用此模式.例如:
// think of these as a bunch of HRESULT type functions
// a return value of 0 means SUCCESS
// a return value of non-zero yields an Error Message
int err;
( !(err=initialize()) && !(err=create_window()) && !(err=run_app() )
|| handle_error(err);
Run Code Online (Sandbox Code Playgroud)
这些类型的操作是否可以按预期的跨平台工作?我已经读过"如果你在一个表达式中读取变量两次,你也写了它,结果是未定义的".但直觉上我觉得短路保证了订单,不是吗?
650*_*502 15
是.
内置的逻辑AND(&&),逻辑OR(||)和逗号运算符(,)是唯一一种二进制运算符C++保证计算将计算左表达式然后(如果不是短路)右表达式(逗号运算符)的情况.当然总是评估两个操作数,先左,然后右).
另请注意,函数参数之间的逗号不是逗号运算符,因此未指定函数参数的计算顺序,甚至更糟糕:例如f(g(h()),i()),调用序列可能是h,i,g,f.
此外,评估订单的保证仅适用于内置运营商; 如果你重新定义它们,那么它们基本上成为函数调用,其中不保证参数的评估顺序以及不执行短路的情况.
其他二元运算符不保证评估的顺序,例如,一个常见的错误是认为:
std::cout << foo() << bar();
Run Code Online (Sandbox Code Playgroud)
调用foo()保证该呼叫之前发生bar()......这是不正确的.
当然,三元 :?运算符的评估顺序也是有保证的,其中在首次评估条件之后,将仅评估其他两个表达式中的一个.
保证评估顺序的另一个地方(有时令新手感到惊讶)是构造函数的成员初始化列表,但在这种情况下,顺序不是表达式中的顺序,而是类中成员声明的顺序...... . 例如:
struct Foo
{
int x, y;
Foo() : y(compute_y()), x(compute_x()) {}
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,保证调用compute_x()将在调用之前完成,compute_y()因为在成员声明x之前y.