[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] Fun little bug...
From: |
Peter Lund |
Subject: |
Re: [Tinycc-devel] Fun little bug... |
Date: |
Wed, 05 Sep 2007 09:51:02 +0200 |
On Tue, 2007-09-04 at 23:29 -0500, Rob Landley wrote:
> int enable = NULL || 0;
>
> And NULL, of course, expands to ( ( void * ) 0 ).
>
> What tcc is saying is that NULL || 0 is illegal. Which is not, in fact, the
> case.
You were right!
'||' requires that the two operands are scalars (§6.5.14 Logical OR
operator, paragraph 1).
Paragraph 2 says "The || operator shall yield 1 if either of its
operands compare unequal to 0; otherwise, it yields 0. The result has
type int."
Okay, so what is a scalar type?
§6.2.5 Types, paragraph 21:
"Arithmetic types and pointer types are collectively called scalar
types. Array and structure types are collectively called aggregate
types.[37])"
Sounds good so far. Arithmetic types comprise integer types and
floating types.
What about "compare unequal to 0"?
§6.3.2.3 Pointers
Paragraph 3:
"An integer constant expression with the value 0, or such an expression
cast to type void *, is called a null pointer constant.[55] If a null
pointer constant is converted to a pointer type, the resulting pointer,
called a null pointer, is guaranteed to compare unequal to a pointer to
any object or function."
Footnote 55: "The macro NULL is defined in <stddef.h> (and other
headers) as a null pointer constant; see 7.17."
That didn't make us any wiser.
§6.5.9 Equality operators
Paragraph 2:
"One of the following shall hold:
— both operands have arithmetic type;
— both operands are pointers to qualified or unqualified versions of
compatible types;
— one operand is a pointer to an object or incomplete type and the other
is a pointer to a
qualified or unqualified version of void; or
— one operand is a pointer and the other is a null pointer constant."
The first requirement is the one that fits 'NULL != 0'.
How pointers compare to integers is not really specified, as far as I
can see. But if we can agree that NULL can be compared to 0 -- and I
believe we can -- then your initial statement (int enable = NULL || 0)
is perfectly valid.
Damn, I learned something new today.
-Peter