gpt4 book ai didi

c++ - c++ 中的逻辑 AND + 赋值,安全吗?

转载 作者:可可西里 更新时间:2023-11-01 15:45:55 26 4
gpt4 key购买 nike

我刚刚学到了这个很棒的模式(实际上是从 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);

这些类型的操作能否按预期跨平台工作?我读过“如果你在你也写它的表达式中读取变量两次,结果是未定义的”。但直觉上我觉得短路可以保证顺序,不是吗?

最佳答案

是的。

内置逻辑与(&&)、逻辑或(||)和逗号运算符(,)是只有对于二元运算符 C++ 保证求值将计算左表达式然后(如果没有短路)右表达式的情况(逗号运算符当然总是计算两个操作数,先左后右)。

另请注意,函数参数之间的逗号不是逗号运算符,因此未指定函数参数的计算顺序,甚至更糟:例如在 f(g(h()),i ()) 调用顺序可能是 h,i,g,f

此外,有关评估顺序的保证仅适用于内置运算符;如果您重新定义它们,那么它们基本上会变成函数调用,其中不能保证参数的计算顺序并且不执行短路。

<罢工>其他二元运算符不保证计算顺序,例如一个常见的错误是认为在:
std::cout << foo() << bar();

foo() 的调用保证在对 bar() 的调用之前发生……这 不是 是的。

(C++17 修复了这个问题,但只在少数非常特殊的情况下,包括左移运算符,因为它用于流)

当然, 三元 :? 运算符的求值顺序也是有保证的,在第一次求值条件后,只会求值其他两个表达式中的一个。

另一个保证计算顺序(有时让新手感到惊讶)的地方是构造函数的成员初始化列表,但在这种情况下,顺序 不是表达式中的顺序,而是类中成员声明的顺序....例如:

struct Foo
{
int x, y;
Foo() : y(compute_y()), x(compute_x()) {}
};

在这种情况下,保证调用 compute_x() 将在调用 compute_y() 之前完成,因为 x 在成员声明中位于 y 之前。

关于c++ - c++ 中的逻辑 AND + 赋值,安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6544139/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com