c++中的逻辑AND+赋值,安全
Logical AND + assignment in c++, safe?
我刚刚(实际上是从javascript)学到了这个很棒的模式,我想把它应用到我的c++代码中。
为了解释这种模式,假设我将一个字符串表示为以下内容的链表:
struct link_char;
struct link_char
{
link_char * next;
char code;
};
请注意,任何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';
}
我的问题是关于安全性,而不是可读性。我知道只要&;没有过载。但是,分配操作是按照正确的顺序进行,还是定义了实现?
上面的例子明确说明了读/写可能发生的地方,但我也希望在可能有副作用的情况下使用这种模式。例如:
// 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);
这些类型的操作是否可以跨平台运行?我读过"如果你在一个表达式中读了两次变量,同时也写了它,结果是未定义的"。但凭直觉,我觉得短路保证了秩序,不是吗?
是。
内置逻辑AND(&&
)、逻辑OR(||
)和逗号运算符(,
。
还要注意,函数参数之间的逗号不是逗号运算符,因此没有指定函数参数的求值顺序,甚至比这更糟:例如,在f(g(h()),i())
中,调用序列可能是h,i,g,f
。
此外,关于评估顺序的保证仅适用于内置运算符;如果重新定义它们,那么它们基本上就变成了函数调用,在函数调用中,参数的求值顺序得不到保证,也不执行短路。
std::cout << foo() << bar();
对CCD_ 6的调用保证在对bar()
的调用之前发生。。。这不是真的。
(C++17修复了这个问题,但仅在少数非常特殊的情况下,包括左移运算符,因为它用于流)
当然,三元:?
运算符的求值顺序也是有保证的,其中在第一次求值条件后,将只求值另外两个表达式中的一个。
另一个保证求值顺序的地方(有时会让新手感到惊讶)是构造函数的成员初始化列表,但在这种情况下,顺序是而不是表达式中的顺序,而是类中成员声明的顺序。。。。例如:
struct Foo
{
int x, y;
Foo() : y(compute_y()), x(compute_x()) {}
};
在这种情况下,保证调用compute_x()
将在调用compute_y()
之前完成,因为在成员声明中x
在y
之前。
这些操作会起作用吗打算跨平台?我读过如果你在一个你也写它的表达式,结果是未定义的"。但是凭直觉我觉得短路保证了秩序,不是吗?
内置的&&
运算符保证了短路评估,这意味着它引入了一个序列点:C++98§5.14/2"第一个表达式的所有副作用,除了临时性(12.2)的破坏,都发生在第二个表达式评估之前"。
所以使用C++没有问题。
不过,在我看来,你建议的用法很不好,因为它晦涩难懂。简单地说,不要使用你必须询问的语言功能,因为其他人很可能也不清楚。此外,在代码中重新注释,请注意,当设置位31时,Windows HRESULT表示失败,这与零/非零非常不同。
干杯&hth。,
- 为"adjacent"变量赋值时出现问题
- C++中的赋值发生,尽管右侧出现异常
- 用C++中的sscanf赋值
- 为std::string的某个索引赋值
- 重载Singly Linked List中的赋值运算符
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- gtest_使用setargpointee在函数中赋值
- 非常量变量只读位置的赋值
- 使用赋值运算符重载从类中返回jobject
- C++数据文件、数组和计算赋值
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 全局作用域中函数指针的赋值
- C++ 布尔复合赋值线程安全
- 复合赋值到布尔值安全吗?
- C++ - 从基类"inherit"重载赋值运算符派生类的安全/标准方法
- 标准库中自赋值不安全的move赋值操作符的基本原理是什么?
- 如果允许将int赋值给float(反之亦然),是否不类型安全?
- c++赋值操作符异常安全
- c++中的逻辑AND+赋值,安全
- 将较小的整数类型赋值给较大的整数类型是否不安全?