Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #112475 > unrolled thread
| Started by | bartc <bc@freeuk.com> |
|---|---|
| First post | 2017-06-18 17:15 +0100 |
| Last post | 2017-06-19 12:34 -0700 |
| Articles | 20 on this page of 111 — 14 participants |
Back to article view | Back to comp.lang.c
Null pointer constant bartc <bc@freeuk.com> - 2017-06-18 17:15 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-18 11:20 -0700
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-18 19:23 +0100
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-18 20:57 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-18 13:38 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-19 04:35 -0700
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-19 18:08 +0000
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-19 21:05 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 12:12 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-19 21:08 -0700
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-19 00:34 +0100
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-19 04:45 -0700
Re: Null pointer constant David Brown <david.brown@hesbynett.no> - 2017-06-19 13:55 +0200
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 13:16 +0100
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-19 16:58 +0100
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-18 20:58 +0000
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 00:11 +0100
Re: Null pointer constant David Brown <david.brown@hesbynett.no> - 2017-06-19 03:21 +0200
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 10:11 +0100
Re: Null pointer constant David Brown <david.brown@hesbynett.no> - 2017-06-19 12:38 +0200
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 13:05 +0100
Re: Null pointer constant David Brown <david.brown@hesbynett.no> - 2017-06-19 14:39 +0200
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-19 11:06 -0400
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-19 15:51 +0000
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-19 12:22 -0400
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-19 17:29 +0000
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-19 13:45 -0400
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 12:31 -0700
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-19 15:10 +0000
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-19 16:53 +0100
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-19 13:06 -0400
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-19 20:03 +0100
Re: Null pointer constant David Brown <david.brown@hesbynett.no> - 2017-06-19 22:37 +0200
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-19 22:10 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 14:25 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-19 22:46 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-20 08:43 -0700
Re: Null pointer constant supercat@casperkitty.com - 2017-06-20 09:17 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-21 00:56 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-21 10:07 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-21 23:52 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-22 10:12 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-22 17:33 -0700
Re: Null pointer constant supercat@casperkitty.com - 2017-06-23 08:54 -0700
Re: Null pointer constant Manfred <invalid@invalid.add> - 2017-06-20 00:00 +0200
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 15:27 -0700
Re: Null pointer constant supercat@casperkitty.com - 2017-06-19 16:38 -0700
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-20 01:14 +0100
Re: Null pointer constant Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-20 12:03 +0100
Re: Null pointer constant Manfred <noname@invalid.add> - 2017-06-20 13:16 +0200
Re: Null pointer constant jameskuyper@verizon.net - 2017-06-20 05:34 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-20 08:49 -0700
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-20 16:35 +0000
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 13:07 -0400
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-20 17:29 +0000
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 13:55 -0400
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-20 18:06 +0000
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 14:42 -0400
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-20 19:10 +0000
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-20 18:31 +0000
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-20 18:36 +0000
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 14:45 -0400
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-20 17:14 +0000
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-20 11:55 -0700
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-20 19:23 +0000
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 15:39 -0400
Re: Null pointer constant scott@slp53.sl.home (Scott Lurndal) - 2017-06-21 13:44 +0000
Re: Null pointer constant scott@slp53.sl.home (Scott Lurndal) - 2017-06-21 13:49 +0000
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-21 23:57 -0700
Re: Null pointer constant Philip Lantz <prl@canterey.us> - 2017-06-28 20:04 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-07-10 08:38 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-20 12:39 -0700
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-20 20:53 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-20 13:07 -0700
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-20 20:50 +0000
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-20 15:35 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-21 00:26 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-21 09:54 -0700
Re: Null pointer constant "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-21 13:09 -0400
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-22 00:53 -0700
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-21 18:09 +0100
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-22 00:50 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 10:24 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-19 22:32 -0700
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 19:40 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 12:08 -0700
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 20:32 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 12:48 -0700
Re: Null pointer constant jameskuyper@verizon.net - 2017-06-19 13:08 -0700
Re: Null pointer constant Nick Bowler <nbowler@draconx.ca> - 2017-06-19 20:40 +0000
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 22:01 +0100
Re: Null pointer constant supercat@casperkitty.com - 2017-06-19 14:15 -0700
Re: Null pointer constant jameskuyper@verizon.net - 2017-06-19 14:25 -0700
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-19 21:06 +0000
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 14:28 -0700
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-19 21:35 +0000
Re: Null pointer constant supercat@casperkitty.com - 2017-06-19 14:48 -0700
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-20 15:38 +0000
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 15:16 -0700
Re: Null pointer constant supercat@casperkitty.com - 2017-06-19 14:29 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 15:18 -0700
Re: Null pointer constant Tim Rentsch <txr@alumni.caltech.edu> - 2017-06-19 22:48 -0700
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-20 15:09 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 10:19 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 10:15 -0700
Re: Null pointer constant David Brown <david.brown@hesbynett.no> - 2017-06-19 22:44 +0200
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 12:24 -0700
Re: Null pointer constant Ike Naar <ike@iceland.freeshell.org> - 2017-06-19 08:21 +0000
Re: Null pointer constant bartc <bc@freeuk.com> - 2017-06-19 10:17 +0100
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 10:04 -0700
Re: Null pointer constant Keith Thompson <kst-u@mib.org> - 2017-06-19 12:34 -0700
Page 1 of 6 [1] 2 3 4 5 6 Next page →
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-18 17:15 +0100 |
| Subject | Null pointer constant |
| Message-ID | <UGx1B.379461$m76.337023@fx35.am4> |
[reposted from comp.std.c]
Take this program:
int main(void) {
int a, b;
int *p;
p = 0; // (1)
p = (a, b, 0); // (2)
p = (a ? 0 : 0); // (3)
}
AIUI, the 0's should all be null pointer constants in these contexts.
But many compilers fail to accept all three numbered lines.
All will do (1), but some report a type warning on (2) and/or (3).
Are lines (2) and (3) valid C?
(gcc reports a type error both those lines.)
--
bartc
[toc] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-18 11:20 -0700 |
| Message-ID | <lnefuhi2dy.fsf@kst-u.example.com> |
| In reply to | #112475 |
bartc <bc@freeuk.com> writes:
> [reposted from comp.std.c]
>
> Take this program:
>
> int main(void) {
> int a, b;
> int *p;
>
> p = 0; // (1)
> p = (a, b, 0); // (2)
> p = (a ? 0 : 0); // (3)
> }
>
> AIUI, the 0's should all be null pointer constants in these contexts.
No, only the first is.
N1570 6.3.2.3p3:
An integer constant expression with the value 0, or such an
expression cast to type void *, is called a *null pointer
constant*. 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.
0 is a null pointer constant. (a, b, 0) and (a ? 0 : 0) are not.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-18 19:23 +0100 |
| Message-ID | <87bmpl40k4.fsf@bsb.me.uk> |
| In reply to | #112475 |
bartc <bc@freeuk.com> writes:
> [reposted from comp.std.c]
>
> Take this program:
>
> int main(void) {
> int a, b;
> int *p;
>
> p = 0; // (1)
> p = (a, b, 0); // (2)
> p = (a ? 0 : 0); // (3)
> }
>
> AIUI, the 0's should all be null pointer constants in these contexts.
Apart from some idea that it should be so, why do you think that?
> But many compilers fail to accept all three numbered lines.
>
> All will do (1),
Whew!
> but some report a type warning on (2) and/or (3).
>
> Are lines (2) and (3) valid C?
No. Every assignment must meet this constraint:
One of the following shall hold:
— the left operand has atomic, qualified, or unqualified arithmetic
type, and the right has arithmetic type;
— the left operand has an atomic, qualified, or unqualified version of
a structure or union type compatible with the type of the right;
— the left operand has atomic, qualified, or unqualified pointer type,
and (considering the type the left operand would have after lvalue
conversion) both operands are pointers to qualified or unqualified
versions of compatible types, and the type pointed to by the left
has all the qualifiers of the type pointed to by the right;
— the left operand has atomic, qualified, or unqualified pointer type,
and (considering the type the left operand would have after lvalue
conversion) one operand is a pointer to an object type, and the
other is a pointer to a qualified or unqualified version of void,
and the type pointed to by the left has all the qualifiers of the
type pointed to by the right;
— the left operand is an atomic, qualified, or unqualified pointer,
and the right is a null pointer constant; or
— the left operand has type atomic, qualified, or unqualified _Bool,
and the right is a pointer.
None of these apply to 2 or 3.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-18 20:57 +0100 |
| Message-ID | <UWA1B.61280$Oz1.5624@fx34.am4> |
| In reply to | #112484 |
On 18/06/2017 19:23, Ben Bacarisse wrote:
> bartc <bc@freeuk.com> writes:
>> int a, b;
>> int *p;
>>
>> p = 0; // (1)
>> p = (a, b, 0); // (2)
>> p = (a ? 0 : 0); // (3)
>> }
>>
>> AIUI, the 0's should all be null pointer constants in these contexts.
>
> Apart from some idea that it should be so, why do you think that?
Because usually, x=y can be written as x=(a,b,y), or x=a?y:y, and an
assignment from y to x still takes place (subject to side-effects from
evaluating a and b).
>> But many compilers fail to accept all three numbered lines.
>>
>> All will do (1),
>
> Whew!
I put it there for comparison. I expect being able to use 0 like a
properly defined NULL is for legacy code. Otherwise NULL would solve
such issues.
>
>> but some report a type warning on (2) and/or (3).
>>
>> Are lines (2) and (3) valid C?
>
> No. Every assignment must meet this constraint:
>
> One of the following shall hold:
> — the left operand is an atomic, qualified, or unqualified pointer,
> and the right is a null pointer constant; or
It's not just assignment. It's also equality ops, relational ops,
satisfying parameter types, return statements, in struct initialisation,
compound literals... all situations where a null pointer constant can
satisfy a requirement to be match a pointer.
Are there special rules for all of those as well?
If just seems an odd exception that the term:
c
can change meaning when it's written as the comma expression:
(a, b, c)
when c happens to be zero, or is any constant expression that reduces to
zero (which gcc accepts).
Would such an arbitrary expression be legal? If so, then I can't see the
difference with a comma expression or a ?: operator, except that those
won't directly reduce to a constant. That will be harder to support,
though not impossible, but that hasn't stopped other hard-to-implement
features being in the language.
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-18 13:38 -0700 |
| Message-ID | <ln60fthvz0.fsf@kst-u.example.com> |
| In reply to | #112489 |
bartc <bc@freeuk.com> writes:
> On 18/06/2017 19:23, Ben Bacarisse wrote:
>> bartc <bc@freeuk.com> writes:
>>> int a, b;
>>> int *p;
>>>
>>> p = 0; // (1)
>>> p = (a, b, 0); // (2)
>>> p = (a ? 0 : 0); // (3)
>>> }
>>>
>>> AIUI, the 0's should all be null pointer constants in these contexts.
>>
>> Apart from some idea that it should be so, why do you think that?
>
> Because usually, x=y can be written as x=(a,b,y), or x=a?y:y, and an
> assignment from y to x still takes place (subject to side-effects from
> evaluating a and b).
To expand on what I wrote previously, given
int *p;
p = (a, b, 0);
the constant 0 *is* a null pointer constant -- but the fact that
it's a null pointer constant turns out not to be relevant. It's only
relevant when the null pointer constant is converted (implicitly or
explicitly) to a null pointer type. An implicit conversion occurs,
for example, when an null pointer constant is the right operand of
an assignment operator whose left operand is of pointer type. Here,
the null pointer constant is the right operand of a comma operator,
which does not cause a conversion to a pointer type.
Both `a, b, 0` and `(a, b, 0)` are expressions that happen to
contain a null pointer constant. That doesn't make them a null
pointer constants themselves.
(A largely irrelevant aside: N1570 6.5.1p5, which describes
parenthesized expressions, neglects to say that a parenthesized
null pointer constant is an null pointer constant. The intent,
that a parenthesized null pointer constant *is* an null pointer
constant, seems to be clear enough that I've never seen a compiler
that doesn't make that assumption. This is a minor wording glitch
in the standard, not a serious issue.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-06-19 04:35 -0700 |
| Message-ID | <kfno9tkmcqx.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #112493 |
Keith Thompson <kst-u@mib.org> writes: > [...] > > (A largely irrelevant aside: N1570 6.5.1p5, which describes > parenthesized expressions, neglects to say that a parenthesized > null pointer constant is an null pointer constant. The intent, > that a parenthesized null pointer constant *is* an null pointer > constant, seems to be clear enough that I've never seen a compiler > that doesn't make that assumption. This is a minor wording glitch > in the standard, not a serious issue.) It almost never matters. An integer constant expression with the value zero is still an integer constant expression with the value zero if put inside parentheses. Casting such an expression to type (void *) produces a pointer type anyway, which can be used almost everywhere a null pointer constant can be, since it is a null pointer and constant expression. AFAICT the only case where it matters is initializing or assigning to a pointer-to-function type, where the null-pointer-constant-ness makes a difference in whether the implementation must accept it. None of that changes your point, but (at least to me) it does lessen the urgency.
[toc] | [prev] | [next] | [standalone]
| From | Nick Bowler <nbowler@draconx.ca> |
|---|---|
| Date | 2017-06-19 18:08 +0000 |
| Message-ID | <oi93um$d5s$1@dont-email.me> |
| In reply to | #112548 |
On Mon, 19 Jun 2017 04:35:18 -0700, Tim Rentsch wrote: > Keith Thompson <kst-u@mib.org> writes: > >> [...] >> >> (A largely irrelevant aside: N1570 6.5.1p5, which describes >> parenthesized expressions, neglects to say that a parenthesized >> null pointer constant is an null pointer constant. The intent, >> that a parenthesized null pointer constant *is* an null pointer >> constant, seems to be clear enough that I've never seen a compiler >> that doesn't make that assumption. This is a minor wording glitch >> in the standard, not a serious issue.) > > It almost never matters. An integer constant expression with the > value zero is still an integer constant expression with the value > zero if put inside parentheses. Casting such an expression to > type (void *) produces a pointer type anyway, which can be used > almost everywhere a null pointer constant can be, since it is a > null pointer and constant expression. AFAICT the only case where > it matters is initializing or assigning to a pointer-to-function > type, where the null-pointer-constant-ness makes a difference in > whether the implementation must accept it. There is another case which affects the resulting type of conditional operators. There is a special case when one of the 2nd or 3rd arguments of a conditional operator is a null pointer constant and the other has pointer type (C11§6.5.15p6): "... if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void." Examples: 0 ? 0 : (int *)0 // this has type int * 0 ? (void *)0 : (int *)0 // this has type int * 0 ? (void *)(void *)0 : (int *)0 // this has type void * Then we can use, say, a _Generic selection to get different values depending on the types of such expressions.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-06-19 21:05 -0700 |
| Message-ID | <kfnefuf8frt.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #112606 |
Nick Bowler <nbowler@draconx.ca> writes: > On Mon, 19 Jun 2017 04:35:18 -0700, Tim Rentsch wrote: > >> Keith Thompson <kst-u@mib.org> writes: >> >>> [...] >>> >>> (A largely irrelevant aside: N1570 6.5.1p5, which describes >>> parenthesized expressions, neglects to say that a parenthesized >>> null pointer constant is an null pointer constant. The intent, >>> that a parenthesized null pointer constant *is* an null pointer >>> constant, seems to be clear enough that I've never seen a compiler >>> that doesn't make that assumption. This is a minor wording glitch >>> in the standard, not a serious issue.) >> >> It almost never matters. An integer constant expression with the >> value zero is still an integer constant expression with the value >> zero if put inside parentheses. Casting such an expression to >> type (void *) produces a pointer type anyway, which can be used >> almost everywhere a null pointer constant can be, since it is a >> null pointer and constant expression. AFAICT the only case where >> it matters is initializing or assigning to a pointer-to-function >> type, where the null-pointer-constant-ness makes a difference in >> whether the implementation must accept it. > > There is another case which affects the resulting type of conditional > operators. There is a special case when one of the 2nd or 3rd arguments > of a conditional operator is a null pointer constant and the other has > pointer type (C116.5.15p6): > > "... if one operand is a null pointer constant, the result has the > type of the other operand; otherwise, one operand is a pointer to > void or a qualified version of void, in which case the result type > is a pointer to an appropriately qualified version of void." > > Examples: > > 0 ? 0 : (int *)0 // this has type int * > 0 ? (void *)0 : (int *)0 // this has type int * > 0 ? (void *)(void *)0 : (int *)0 // this has type void * > > Then we can use, say, a _Generic selection to get different values > depending on the types of such expressions. Right. Thank you for reminding me. In fact we don't need _Generic to turn this into a problem - even in C90 it can disguise an incompatible pointer type.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-19 12:12 -0700 |
| Message-ID | <lnmv93g5bk.fsf@kst-u.example.com> |
| In reply to | #112548 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> [...]
>>
>> (A largely irrelevant aside: N1570 6.5.1p5, which describes
>> parenthesized expressions, neglects to say that a parenthesized
>> null pointer constant is an null pointer constant. The intent,
>> that a parenthesized null pointer constant *is* an null pointer
>> constant, seems to be clear enough that I've never seen a compiler
>> that doesn't make that assumption. This is a minor wording glitch
>> in the standard, not a serious issue.)
>
> It almost never matters. An integer constant expression with the
> value zero is still an integer constant expression with the value
> zero if put inside parentheses. Casting such an expression to
> type (void *) produces a pointer type anyway, which can be used
> almost everywhere a null pointer constant can be, since it is a
> null pointer and constant expression. AFAICT the only case where
> it matters is initializing or assigning to a pointer-to-function
> type, where the null-pointer-constant-ness makes a difference in
> whether the implementation must accept it.
>
> None of that changes your point, but (at least to me) it does
> lessen the urgency.
(void*)0 is not a valid definition for the NULL macro, because it's not
fully protected by parentheses (N1570 7.1.2p5). ((void*)0) is not a
valid definition *unless* we assume that a parenthesized null pointer
constant is a null pointer constant.
On the other hand, no implementation is going to define the NULL macro
in a way that the implementation itself doesn't treat as a null pointer
constant.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-06-19 21:08 -0700 |
| Message-ID | <kfna8538fo9.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #112613 |
Keith Thompson <kst-u@mib.org> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: > >> Keith Thompson <kst-u@mib.org> writes: >> >>> [...] >>> >>> (A largely irrelevant aside: N1570 6.5.1p5, which describes >>> parenthesized expressions, neglects to say that a parenthesized >>> null pointer constant is an null pointer constant. The intent, >>> that a parenthesized null pointer constant *is* an null pointer >>> constant, seems to be clear enough that I've never seen a compiler >>> that doesn't make that assumption. This is a minor wording glitch >>> in the standard, not a serious issue.) >> >> It almost never matters. An integer constant expression with the >> value zero is still an integer constant expression with the value >> zero if put inside parentheses. Casting such an expression to >> type (void *) produces a pointer type anyway, which can be used >> almost everywhere a null pointer constant can be, since it is a >> null pointer and constant expression. AFAICT the only case where >> it matters is initializing or assigning to a pointer-to-function >> type, where the null-pointer-constant-ness makes a difference in >> whether the implementation must accept it. >> >> None of that changes your point, but (at least to me) it does >> lessen the urgency. > > (void*)0 is not a valid definition for the NULL macro, because it's not > fully protected by parentheses (N1570 7.1.2p5). ((void*)0) is not a > valid definition *unless* we assume that a parenthesized null pointer > constant is a null pointer constant. Yes, that is just the Standard's sneaky way of requiring NULL to be defined as 0 while /appearing/ that it offers a choice. ;)
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-19 00:34 +0100 |
| Message-ID | <87shiw3m6c.fsf@bsb.me.uk> |
| In reply to | #112489 |
bartc <bc@freeuk.com> writes: > On 18/06/2017 19:23, Ben Bacarisse wrote: >> bartc <bc@freeuk.com> writes: > >>> int a, b; >>> int *p; >>> >>> p = 0; // (1) >>> p = (a, b, 0); // (2) >>> p = (a ? 0 : 0); // (3) >>> } >>> >>> AIUI, the 0's should all be null pointer constants in these contexts. >> >> Apart from some idea that it should be so, why do you think that? > > Because usually, x=y can be written as x=(a,b,y), or x=a?y:y, and an > assignment from y to x still takes place (subject to side-effects from > evaluating a and b). Certain syntactic forms play special roles in C. For example you can't write (expr, x) = y; because the comma form is not a lvalue. Similarly, only 0 is a recognised null pointer constant. No matter how many more forms C were to decide to permit, some cases would still remain as "surprises". Usually, if f() returns y, writing x=f(); is the same as x=y; (barring the side-effects) but there is no way a compiler will be able to check the the int returned by f is in fact zero. <snip> > It's not just assignment. It's also equality ops, relational ops, > satisfying parameter types, return statements, in struct > initialisation, compound literals... all situations where a null > pointer constant can satisfy a requirement to be match a pointer. > > Are there special rules for all of those as well? Why don't you look? I don't fancy answering all of your questions when there's a document that does that already. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-06-19 04:45 -0700 |
| Message-ID | <kfnk248mc95.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #112515 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > [...] I don't fancy answering all of your questions when > there's a document that does that already. Without mentioning any names, some people have demonstrated that they are perfectly capable of looking up such things when it suits their purposes, but don't bother otherwise. I have come around to the point of view that questions of this kind are best completely ignored, despite the temptation to answer them - better for me, better for the group, and ultimately better for the person doing the asking. For what that might be worth.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-19 13:55 +0200 |
| Message-ID | <oi8dsc$phv$1@dont-email.me> |
| In reply to | #112549 |
On 19/06/17 13:45, Tim Rentsch wrote: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> [...] I don't fancy answering all of your questions when >> there's a document that does that already. > > Without mentioning any names, some people have demonstrated > that they are perfectly capable of looking up such things > when it suits their purposes, but don't bother otherwise. That description could apply to almost anyone. One big variation is in the "purpose" - what is the motivation for looking things up or not doing so? > > I have come around to the point of view that questions of > this kind are best completely ignored, despite the temptation > to answer them - better for me, better for the group, and > ultimately better for the person doing the asking. For > what that might be worth. > But is it better for other people who might be viewing the thread, now or in the future (yes, /some/ people really do search archives before posting a new question!) ? (That is a serious question, not a rhetorical one.)
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-19 13:16 +0100 |
| Message-ID | <TgP1B.115795$dp2.54588@fx13.am4> |
| In reply to | #112515 |
On 19/06/2017 00:34, Ben Bacarisse wrote: > bartc <bc@freeuk.com> writes: >> Are there special rules for all of those as well? > > Why don't you look? I don't fancy answering all of your questions when > there's a document that does that already. Is there any point to this to newsgroup then? Or to any other resources that explain C. Because after all it tells you everything you could possibly want to know. -- bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-19 16:58 +0100 |
| Message-ID | <87h8zcdl4v.fsf@bsb.me.uk> |
| In reply to | #112554 |
bartc <bc@freeuk.com> writes: > On 19/06/2017 00:34, Ben Bacarisse wrote: >> bartc <bc@freeuk.com> writes: > >>> Are there special rules for all of those as well? >> >> Why don't you look? I don't fancy answering all of your questions when >> there's a document that does that already. > > Is there any point to this to newsgroup then? Or to any other > resources that explain C. Yes, it serves several purposes. And you may even find other people prepared to look up the standard and quote the passages to you that answer the questions you posed. I'm just letting you know that I don't fancy doing that. > Because after all it tells you everything you could possibly want to > know. Utter nonsense. The groups is full of threads that can not be resolved by reading the standard and I am sure you know this. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2017-06-18 20:58 +0000 |
| Message-ID | <slrn3vfsokdqhs.r2.ike@iceland.freeshell.org> |
| In reply to | #112475 |
On 2017-06-18, bartc <bc@freeuk.com> wrote:
> [reposted from comp.std.c]
>
> Take this program:
>
> int main(void) {
> int a, b;
> int *p;
>
> p = 0; // (1)
> p = (a, b, 0); // (2)
> p = (a ? 0 : 0); // (3)
> }
>
> AIUI, the 0's should all be null pointer constants in these contexts.
>
> But many compilers fail to accept all three numbered lines.
>
> All will do (1), but some report a type warning on (2) and/or (3).
>
> Are lines (2) and (3) valid C?
>
> (gcc reports a type error both those lines.)
A null pointer constant is a special case of an integer constant expression.
According to 6.6.6:
An integer constant expression 117) shall have integer type and
shall only have operands that are integer constants, enumeration
constants, character constants, sizeof expressions whose results
are integer constants, _Alignof expressions, and floating constants
that are the immediate operands of casts. Cast operators in an
integer constant expression shall only convert arithmetic types
to integer types, except as part of an operand to the sizeof or
_Alignof operator
so neither (a, b, 0) nor (a ? 0 : 0) are integer constant expressions,
and therefore not null pointer constants.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-19 00:11 +0100 |
| Message-ID | <jMD1B.215949$gM7.179726@fx44.am4> |
| In reply to | #112499 |
On 18/06/2017 21:58, Ike Naar wrote: > On 2017-06-18, bartc <bc@freeuk.com> wrote: >> p = (a, b, 0); // (2) >> p = (a ? 0 : 0); // (3) > A null pointer constant is a special case of an integer constant expression. > > According to 6.6.6: > An integer constant expression 117) shall have integer type and > shall only have operands that are integer constants, enumeration > constants, character constants, sizeof expressions whose results > are integer constants, _Alignof expressions, and floating constants > that are the immediate operands of casts. Cast operators in an > integer constant expression shall only convert arithmetic types > to integer types, except as part of an operand to the sizeof or > _Alignof operator > > so neither (a, b, 0) nor (a ? 0 : 0) are integer constant expressions, > and therefore not null pointer constants. (a?b:c) can be a constant expression, provided a, b and c are constants. When a is constant then: p = 1 ? 0 : q; (p, q both int*) passes in all compilers I tried (even though c - that is, 'q' - is not constant). Although strangely: p = 1 ? 0 : 0; gives a problem in two compilers (even though all elements are constant). But, the restrictions on being able to use 0 as a null pointer constant only in certain kinds of expressions sound like another quirk. -- bartc
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-19 03:21 +0200 |
| Message-ID | <oi78on$hu7$1@dont-email.me> |
| In reply to | #112511 |
On 19/06/17 01:11, bartc wrote: > On 18/06/2017 21:58, Ike Naar wrote: >> On 2017-06-18, bartc <bc@freeuk.com> wrote: > >>> p = (a, b, 0); // (2) >>> p = (a ? 0 : 0); // (3) > >> A null pointer constant is a special case of an integer constant >> expression. >> >> According to 6.6.6: >> An integer constant expression 117) shall have integer type and >> shall only have operands that are integer constants, enumeration >> constants, character constants, sizeof expressions whose results >> are integer constants, _Alignof expressions, and floating constants >> that are the immediate operands of casts. Cast operators in an >> integer constant expression shall only convert arithmetic types >> to integer types, except as part of an operand to the sizeof or >> _Alignof operator >> >> so neither (a, b, 0) nor (a ? 0 : 0) are integer constant expressions, >> and therefore not null pointer constants. > > (a?b:c) can be a constant expression, provided a, b and c are constants. > I presume you haven't bothered looking at the standard to see what a "constant expression" actually /is/, in the C standards? And in particular, you haven't looked at what an "integer constant expression" is? > When a is constant then: > > p = 1 ? 0 : q; (p, q both int*) > > passes in all compilers I tried (even though c - that is, 'q' - is not > constant). Although strangely: > > p = 1 ? 0 : 0; > > gives a problem in two compilers (even though all elements are constant). > > But, the restrictions on being able to use 0 as a null pointer constant > only in certain kinds of expressions sound like another quirk. > This is clearly explained in the standards.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-19 10:11 +0100 |
| Message-ID | <9zM1B.193976$KK7.183000@fx12.am4> |
| In reply to | #112522 |
On 19/06/2017 02:21, David Brown wrote: > On 19/06/17 01:11, bartc wrote: >> (a?b:c) can be a constant expression, provided a, b and c are constants. >> > > I presume you haven't bothered looking at the standard to see what a > "constant expression" actually /is/, in the C standards? And in > particular, you haven't looked at what an "integer constant expression" is? The standard says this: "constant-expression: conditional-expression" A condition-expression can be a a?b:c operation. But it was hardly necessary to check that, as plenty of programs rely on using ?: in constant expressions, including that assert macro of a few weeks back which declared an array parameter bound as either 1 or 0. >> But, the restrictions on being able to use 0 as a null pointer >> constant only in certain kinds of expressions sound like another quirk. >> > > This is clearly explained in the standards. The standard says this: 6.3.2.3p3: "An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant." So this term: p == (a,b, 0); can be considered to be: p == (a,b, null-pointer-constant); provided the embedded 0 can be considered an expression. But since: c; is clearly an expression, then it is not going to be stop being an expression when expanded to: (a, b, c); Otherwise writing: p = 0; // int*p can't work because, although 0 is a null-pointer-constant, the composite assignment will embed the 0 so that it is no longer a null-pointer-constant. But given that the 0 in (a,b,0) appears to be a null-pointer-constant, the machinations required within the rest of the standard to stop that being used legally against pointer types is not at all clear. (Yes, I understand that for people like you, such things are black and white. Provided something is explained somewhere, not matter how thick a manual is or how long you have to spend on the internet, then it cannot possibly be too complicated or too confusing.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-19 12:38 +0200 |
| Message-ID | <oi89cl$t3d$1@dont-email.me> |
| In reply to | #112534 |
On 19/06/17 11:11, bartc wrote: > On 19/06/2017 02:21, David Brown wrote: >> On 19/06/17 01:11, bartc wrote: > >>> (a?b:c) can be a constant expression, provided a, b and c are constants. >>> >> >> I presume you haven't bothered looking at the standard to see what a >> "constant expression" actually /is/, in the C standards? And in >> particular, you haven't looked at what an "integer constant >> expression" is? > > The standard says this: > > "constant-expression: conditional-expression" > > A condition-expression can be a a?b:c operation. > > But it was hardly necessary to check that, as plenty of programs rely on > using ?: in constant expressions, including that assert macro of a few > weeks back which declared an array parameter bound as either 1 or 0. Yes, and did you also look up "/integer/ constant expression" - the particular type of constant expression Ike referred to? > >>> But, the restrictions on being able to use 0 as a null pointer >>> constant only in certain kinds of expressions sound like another quirk. >>> >> >> This is clearly explained in the standards. > > The standard says this: > > 6.3.2.3p3: > > "An integer constant expression with the value 0, or such an > expression cast to type void *, is called a null pointer constant." > > So this term: > > p == (a,b, 0); > > can be considered to be: > > p == (a,b, null-pointer-constant); Correct. > > provided the embedded 0 can be considered an expression. But since: > > c; > > is clearly an expression, then it is not going to be stop being an > expression when expanded to: > > (a, b, c); Yes. > > Otherwise writing: > > p = 0; // int*p > > can't work because, although 0 is a null-pointer-constant, the composite > assignment will embed the 0 so that it is no longer a > null-pointer-constant. > > But given that the 0 in (a,b,0) appears to be a null-pointer-constant, > the machinations required within the rest of the standard to stop that > being used legally against pointer types is not at all clear. There is a big difference between (a, b, 0) and (a ? 0 : 0). In the first case, you have the comma operator, so the type of the expression comes entirely from the right hand side. In the second case, you have a conditional operator. Look at the rules in 6.5.15. There is no option for both the "b" and "c" parts of a?b:c to be null pointer constants (perhaps because that would be a useless expression). The only way to interpret "a ? 0 : 0" to fit the constraints is to consider both zeros to be ints. So you are trying to assign the /int/ value 0 to a pointer, not the null pointer constant. > > (Yes, I understand that for people like you, such things are black and > white. Provided something is explained somewhere, not matter how thick a > manual is or how long you have to spend on the internet, then it cannot > possibly be too complicated or too confusing.) > Of course these things can be complicated. They are not an issue in real-world programming, since the examples are totally artificial and unrealistic. In this particular case, I had to look up the rules in the standard to see exactly what was happening. But the difference between you and me is that I /do/ look them up, rather than posting complaints about how hard it all is, or comparing the warning messages from a few compilers as though that would make the rules clear. I might still make mistakes and be corrected here - but at least I /try/ to understand and to learn. And since I am /using/ C, that is fine for my purposes. You are trying to make a C compiler - you need to know these things accurately, and get them right. You need to know the standards inside out and back to front - they are the specifications for the program you are writing. It is, of course, absolutely fine to have questions or misunderstandings and look for help in clearing them up - but it is not remotely reasonable for you not to have bothered reading the bits that are clearly described.
[toc] | [prev] | [next] | [standalone]
Page 1 of 6 [1] 2 3 4 5 6 Next page →
Back to top | Article view | comp.lang.c
csiph-web