This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/36588] New: Request warnings about the precedence of the unary - over the binary * and /
- From: "vincent at vinc17 dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 21 Jun 2008 10:48:21 -0000
- Subject: [Bug c/36588] New: Request warnings about the precedence of the unary - over the binary * and /
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
The problem: it is too easy to write incorrect code with the unary "-", e.g.
"- i / 2" (which means "(- i) / 2")
when one really wants "- (i / 2)". The reasons are:
1. Whereas the binary "-" has a lower precedence than the binary "*" (multiply)
and "/" (divide), the unary "-" has a higher precedence. It is easy to forget
this difference, in particular because the same symbol is used with two
different precedences. For instance, the expressions "0 - i / 2" and "- i / 2"
look the same, but the former corresponds to "0 - (i / 2)" and the latter
corresponds to "(- i) / 2".
2. Mathematically (in a ring), the precedence of the unary "-" (for the
opposite) vs "*" (multiply) does not matter since the result does not depend on
the precedence, so that it is never explicited in practice and what the writer
of a math expression really thinks depends on the context.
The following code shows such a problem that can occur in practice: the unary
"-" in "k = - i / 2" yields an integer overflow, hence undefined behavior. The
user may not be aware of it. And the fact that this bug is hidden with -O2
optimizations makes it worse. For instance, when compiling this code without
optimizations, I get:
j = 1073741824
k = -1073741824
(which is not the intended result). With -O2 optimizations, I get:
j = 1073741824
k = 1073741824
Adding the following warnings could avoid bugs like this one:
warning: suggest parentheses around unary - in operand of *
warning: suggest parentheses around unary - in operand of /
Note: such warnings should also apply to floating-point expressions as they can
be affected in the rounding directions FE_DOWNWARD and FE_UPWARD.
#include <stdio.h>
#include <limits.h>
int main (void)
{
int i, j, k;
i = INT_MIN;
j = 0 - i / 2;
k = - i / 2;
printf ("j = %d\n", j);
printf ("k = %d\n", k);
return 0;
}
--
Summary: Request warnings about the precedence of the unary -
over the binary * and /
Product: gcc
Version: 4.3.1
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: vincent at vinc17 dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36588