C++11 什么时候给出关于运算符优先级的警告?

When does C++11 give warnings about operator precedence?

写代码的时候,很长一段时间都知道&&的优先级高于||;然而,使用 C++11 标准编译它给了我一个警告,我现在应该在单个语句中同时使用括号时使用括号。

现在我收到一条警告,指出合并 >> 和 + 也应该有括号。现在我的陈述看起来真的很难看,周围有 5 个或更多的括号。

1) 是否有资源说明哪些运算符组合现在需要括号?

2) 有没有办法让运算符优先级警告静音,但保留其他警告?

编译器 gcc 带有标志 -O2 -Wall -g

当我添加标志时出现警告 -std=c++11

示例表达式:

(((string[0] << CHAR_BIT) + string[1] << CHAR_BIT) + string[2] << CHAR_BIT) + string[3];

参见 gcc manual:

-Wparentheses

Warn if parentheses are omitted in certain contexts, such as when there is an assignment in a context where a truth value is expected, or when operators are nested whose precedence people often get confused about.

Also warn if a comparison like x<=y<=z appears; this is equivalent to (x<=y ? 1 : 0) <= z, which is a different interpretation from that of ordinary mathematical notation.

Also warn for dangerous uses of the GNU extension to ?: with omitted middle operand. When the condition in the ?: operator is a boolean expression, the omitted value is always 1. Often programmers expect it to be a value computed inside the conditional expression instead.

(我加了重点)

要关闭此行为,请将 -Wno-parentheses 指定为 gcc/g++

When does C++11 give warnings about operator precedence?

标准需要诊断消息(请注意,标准不区分警告和停止编译的错误)的唯一情况是程序违反标准。除非编译器免除 "no diagnostic required".

的措辞

所有其他警告对于编译器都是可选的,标准不需要。


1) Is there a resource that says which combinations of operators now require parentheses?

否,因为不需要括号。该警告只是编译器的一个建议。程序格式正确。

The warnings came in when I added the flag -std=c++11

不管标准参数如何,我的 GCC 都会发出警告。


2) Is there a way to silence just the operator precedence warnings, but to keep the other warnings?

警告本身告诉它启用了哪个警告选项(这是来自我的 GCC 的警告):

warning: suggest parentheses around '+' inside '<<' [-Wparentheses]

要禁用,可以使用相应的选项来禁用它:-Wno-WHATEVER.


Now my statements look really ugly, with 5 or more parentheses floating around them.

我建议改为提取重复结构,并重新使用标准算法:

std::accumulate(string, string + 4, 0, [](auto sum, auto value) {
    return (sum << CHAR_BIT) + value;
});

括号少了很多 :) 请注意,在 C++11(C++14 之前)中,您不能使用 auto 作为 lambda 参数的类型。不知道你用的是什么类型