Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #112475 > unrolled thread

Null pointer constant

Started bybartc <bc@freeuk.com>
First post2017-06-18 17:15 +0100
Last post2017-06-19 12:34 -0700
Articles 20 on this page of 111 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  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 2 of 6 — ← Prev page 1 [2] 3 4 5 6  Next page →


#112552

Frombartc <bc@freeuk.com>
Date2017-06-19 13:05 +0100
Message-ID<U5P1B.148289$GY6.107654@fx30.am4>
In reply to#112540
On 19/06/2017 11:38, David Brown wrote:
> On 19/06/17 11:11, bartc wrote:

>> 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?

Are you referring to 6.6.6? According to that, 0+0 is not an integer 
constant expression as "+" isn't one of the allowed operators that it lists.

If you're suggesting that ?: cannot yield an integer constant 
expression, then that assert macro that forces an error by declaring 
array bounds of -1, would be illegal.


>> 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).

(a,b,0) can't be an integer constant expression, even if a and b are 
constants, because the language considers that nonsensical.

But I don't see why:

   p = (a,b,0);

can't be well-behaved. You evaluate a and b, then assign 0 to pointer p. 
The language doesn't like it because implementing it is awkward (the 
null-pointer-constant-ness of the terminal 0 doesn't propagate up in the 
same way as the type of it would).

> 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).

I would have to disagree with the standard then. Either of those zeros 
could be hidden behind macros and/or expressions that yield zero. It's 
an arbitrary restriction. It might as well say that:

   int a = (x?0:0);

shouldn't be allowed.

(I would however have agreed with a decision not to have null pointer 
constants, in the form of an integer 0 expression, at all. Not if all 
these restrictions and special rules have to be put in place. NULL can 
be used instead, or an explicit cast.)

BTW 6.5.15 also says this:

  — both operands have void type;

which sounds rather mysterious. What it presumably means is that ?: can 
be used as statement by itself. But in that case both branches have to 
call functions return void. (I think it would have been better to either 
disallow standalone use, or allow the branches to have mixed types.)

> 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.

I don't want to do any more work than is necessary.

If X is needed to implement a feature properly or to diagnose an error, 
but only some compilers bother, then I won't either.

I was going to allow 0 being compatible with a pointer in any context, 
then I found that I didn't need to.

But this issue came up because I thought I'd seen NULL being defined as 
0 instead of (void*)0, and I'd copied that. Presumably some code must 
have used (a,b,NULL).

Now I've changed it to (void*)0 and hopefully the problem will go away.

   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.

Again, they are certainly not clear. I would have said:

  For a null pointer constant use NULL if possible, as that will always 
have pointer type (of void*).

  Using constant 0, or an expression that reduces to a compile-time 
constant of 0, can sometimes be used, without a cast, when a null 
pointer value is needed, but not everywhere you would normally expect to 
use a 0.

Deliberately keeping it vague enough to discourage its use.

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#112557

FromDavid Brown <david.brown@hesbynett.no>
Date2017-06-19 14:39 +0200
Message-ID<oi8geb$a5m$1@dont-email.me>
In reply to#112552
On 19/06/17 14:05, bartc wrote:
> On 19/06/2017 11:38, David Brown wrote:
>> On 19/06/17 11:11, bartc wrote:
> 
>>> 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?
> 
> Are you referring to 6.6.6? According to that, 0+0 is not an integer
> constant expression as "+" isn't one of the allowed operators that it
> lists.
> 
> If you're suggesting that ?: cannot yield an integer constant
> expression, then that assert macro that forces an error by declaring
> array bounds of -1, would be illegal.

I have now read the paragraph (6.6p6) a little better.  It does not
limited the /operators/ used to make the "integer constant expression" -
it limits the /operands/ used with operators.  So a conditional like
this /can/ be an integer constant expression.


> 
> 
>>> 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).
> 
> (a,b,0) can't be an integer constant expression, even if a and b are
> constants, because the language considers that nonsensical.
> 

True.  I suspect that is because the comma operator has a sequence
point, and it would not make sense to have a sequence point in a
constant expression.

(For what it is worth, I am not a fan of the comma operator, and I am
not keen on sequence points inside an expression other than an assignment.)

> But I don't see why:
> 
>   p = (a,b,0);
> 
> can't be well-behaved. You evaluate a and b, then assign 0 to pointer p.
> The language doesn't like it because implementing it is awkward (the
> null-pointer-constant-ness of the terminal 0 doesn't propagate up in the
> same way as the type of it would).
> 

No, the language does not like it because the sequence points spoil the
special nature of the a pointer constant - there needs to be some rules
to say when 0 is an int, and when it is a null pointer constant.

You can write:

	p = (a, b, (void*) 0);

You can also write:

	p = (a, b, NULL);

That is one of the purposes of having the NULL macro - it is /always/ a
null pointer constant.


>> 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).
> 
> I would have to disagree with the standard then. Either of those zeros
> could be hidden behind macros and/or expressions that yield zero. It's
> an arbitrary restriction. It might as well say that:
> 
>   int a = (x?0:0);
> 
> shouldn't be allowed.

Should (x ? 0 : 0) be considered the int constant 0, the null pointer
constant, or should the decision be left to constraint fitting on the
rest of the expression (in this case, the assignment)?  I think it would
be wrong to exclude an int of value 0 here.  If the rest of the grammar
would allow the decision to be put off until later, then that would seem
reasonable - if not, then giving a type of "int" should trump the null
pointer constant.  I don't know if the decision could be left for later
- someone else will have to tell you the answer there.

> 
> (I would however have agreed with a decision not to have null pointer
> constants, in the form of an integer 0 expression, at all. Not if all
> these restrictions and special rules have to be put in place. NULL can
> be used instead, or an explicit cast.)
> 

Agreed.  The use of 0 for a null pointer constant is historical, and
must exist for backwards compatibility.  It is also ideal as a
representation, for implementation efficiency.  But in most cases it is
probably better to use NULL than 0 for a null pointer.

> BTW 6.5.15 also says this:
> 
>  — both operands have void type;
> 
> which sounds rather mysterious. What it presumably means is that ?: can
> be used as statement by itself. But in that case both branches have to
> call functions return void. (I think it would have been better to either
> disallow standalone use, or allow the branches to have mixed types.)
> 

Agreed, it sounds somewhat mysterious.

>> 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.
> 
> I don't want to do any more work than is necessary.

Who does?  But you need to do the work that /is/ necessary.

> 
> If X is needed to implement a feature properly or to diagnose an error,
> but only some compilers bother, then I won't either.

You are aiming to be the lowest of all compilers, with the least
features and the most bugs?

> 
> I was going to allow 0 being compatible with a pointer in any context,
> then I found that I didn't need to.
> 
> But this issue came up because I thought I'd seen NULL being defined as
> 0 instead of (void*)0, and I'd copied that. Presumably some code must
> have used (a,b,NULL).
> 
> Now I've changed it to (void*)0 and hopefully the problem will go away.
> 
>   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.
> 
> Again, they are certainly not clear. I would have said:
> 
>  For a null pointer constant use NULL if possible, as that will always
> have pointer type (of void*).
> 
>  Using constant 0, or an expression that reduces to a compile-time
> constant of 0, can sometimes be used, without a cast, when a null
> pointer value is needed, but not everywhere you would normally expect to
> use a 0.
> 
> Deliberately keeping it vague enough to discourage its use.
> 

[toc] | [prev] | [next] | [standalone]


#112578

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-06-19 11:06 -0400
Message-ID<867a18ef-7ae6-2fe1-7f11-563b0572425c@verizon.net>
In reply to#112557
On 06/19/2017 08:39 AM, David Brown wrote:
> On 19/06/17 14:05, bartc wrote:
...
>> Are you referring to 6.6.6? According to that, 0+0 is not an integer
>> constant expression as "+" isn't one of the allowed operators that it
>> lists.
>>
>> If you're suggesting that ?: cannot yield an integer constant
>> expression, then that assert macro that forces an error by declaring
>> array bounds of -1, would be illegal.
>
> I have now read the paragraph (6.6p6) a little better.  It does not
> limited the /operators/ used to make the "integer constant expression" -
> it limits the /operands/ used with operators.  So a conditional like
> this /can/ be an integer constant expression.

While 0+0 is fine,  6-2*3 is not: the right operand of the subtraction 
operator is a multiplication expression, which doesn't fall into any of 
listed categories of allowed operands. I suspect that the committee 
intended to allow 6-2*3, and similarly complicated expressions, so I 
think that 6.6p6 is flawed; I think it was probably intended to also 
allow for operands that are themselves integer constant expressions. 
Also, it only restricts operands. If an expression does not have any 
operands (such as the primary-expression "a"), 6.6p6 doesn't impose any 
restrictions on it, which was certainly not the intent.

I think that the intent of 6.6p6 would have been more accurately 
expressed by saying: "An _integer constant expression_ shall have 
integer type and shall be an integer constant, an enumeration constant, 
a character constant, a sizeof expression whose result is an integer 
constant, a floating point constant that is the immediate operand of a 
cast, or expression whose operands are all, recursively, integer 
constant expressions."

...
> ... I am
> not keen on sequence points inside an expression other than an assignment.)

Keep in mind that C doesn't have sequence points associated with 
assignment expressions.

[toc] | [prev] | [next] | [standalone]


#112580

FromIke Naar <ike@iceland.freeshell.org>
Date2017-06-19 15:51 +0000
Message-ID<slrn3vfsokfstu.lnq.ike@iceland.freeshell.org>
In reply to#112578
On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
> On 06/19/2017 08:39 AM, David Brown wrote:
>> I have now read the paragraph (6.6p6) a little better.  It does not
>> limited the /operators/ used to make the "integer constant expression" -
>> it limits the /operands/ used with operators.  So a conditional like
>> this /can/ be an integer constant expression.
>
> While 0+0 is fine,  6-2*3 is not: the right operand of the subtraction 
> operator is a multiplication expression, which doesn't fall into any of 
> listed categories of allowed operands.

According to the syntax, the right operand of the subtraction operator
is always a multiplicative-expression.

6.5.6
additive-expression:
  multiplicative-expression
  additive-expression + multiplicative-expression
  additive-expression - multiplicative-expression

The multiplicative-expression can (via cast-exporession,
unary-expression, postfix-expression, primary-expression, constant)
produce an integer constant.

I don't think there is any dispute about 0-0 being a null pointer constant,
even though each 0 is derived from a multiplicative-expression.

For what it's worth, gcc 4.8.4 accepts 6-2*3 as a null pointer constant.

[toc] | [prev] | [next] | [standalone]


#112586

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-06-19 12:22 -0400
Message-ID<170019a8-640f-5152-5f98-d0270dc71b47@verizon.net>
In reply to#112580
On 06/19/2017 11:51 AM, Ike Naar wrote:
> On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
>> On 06/19/2017 08:39 AM, David Brown wrote:
>>> I have now read the paragraph (6.6p6) a little better.  It does not
>>> limited the /operators/ used to make the "integer constant expression" -
>>> it limits the /operands/ used with operators.  So a conditional like
>>> this /can/ be an integer constant expression.
>>
>> While 0+0 is fine,  6-2*3 is not: the right operand of the subtraction
>> operator is a multiplication expression, which doesn't fall into any of
>> listed categories of allowed operands.
>
> According to the syntax, the right operand of the subtraction operator
> is always a multiplicative-expression.

True, but not relevant, which I was trying to hint at by referring to it 
as a "multiplication expression" (which isn't one of the standard-define 
grammar terms), rather than "multiplicative-expression". As I'm using 
the term, a "multiplicative expression" is one that actually has a 
multiplication as it's operator.

For comparison: 5 is a constant. As a result, it is also a 
primary-expression, a postfix-expression, a unary-expression, and a 
multiplicative-expression (assuming it occurs in a location where 
expressions of one of those types are permitted by the grammar). But, as 
a constant, 5 meets the requirements in 6.6p6 for an operand in an 
integer constant expression. In contrast, the only one of those terms 
that describes 2*3 is multiplicative-expression, and that's not enough 
to qualify it for use in that context.
As I stated in text which you clipped, I'm sure this is not the intent 
of the committee. I've frequently written code based upon the assumption 
that committee did intend to allow such things.

[toc] | [prev] | [next] | [standalone]


#112603

FromIke Naar <ike@iceland.freeshell.org>
Date2017-06-19 17:29 +0000
Message-ID<slrn3vfsokg2nd.v0.ike@iceland.freeshell.org>
In reply to#112586
On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
> On 06/19/2017 11:51 AM, Ike Naar wrote:
>> On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
>>> On 06/19/2017 08:39 AM, David Brown wrote:
>>>> I have now read the paragraph (6.6p6) a little better.  It does not
>>>> limited the /operators/ used to make the "integer constant expression" -
>>>> it limits the /operands/ used with operators.  So a conditional like
>>>> this /can/ be an integer constant expression.
>>>
>>> While 0+0 is fine,  6-2*3 is not: the right operand of the subtraction
>>> operator is a multiplication expression, which doesn't fall into any of
>>> listed categories of allowed operands.
>>
>> According to the syntax, the right operand of the subtraction operator
>> is always a multiplicative-expression.
>
> True, but not relevant, which I was trying to hint at by referring to it 
> as a "multiplication expression" (which isn't one of the standard-define 
> grammar terms), rather than "multiplicative-expression". As I'm using 
> the term, a "multiplicative expression" is one that actually has a 
> multiplication as it's operator.
>
> For comparison: 5 is a constant. As a result, it is also a 
> primary-expression, a postfix-expression, a unary-expression, and a 
> multiplicative-expression (assuming it occurs in a location where 
> expressions of one of those types are permitted by the grammar). But, as 
> a constant, 5 meets the requirements in 6.6p6 for an operand in an 
> integer constant expression. In contrast, the only one of those terms 
> that describes 2*3 is multiplicative-expression, and that's not enough 
> to qualify it for use in that context.

  6.6
  constant-expression
    conditional-expression

  6.6p6
  An integer constant expression shall have integer type and
  shall only have operands that are integer constants, [...]

I take it that the term 'operands' in this sentence refers to the
operands that appear in the full derivation of the constant-expression,
that is, in the derivation

      constant-expression
  ==>
      conditional-expression
  ==>
      ...
  ==>
      additive-expression
  ==>
      multiplicative-expression - multiplicative-expression
  ==> 
      ...
  ==>
      postfix-expression - postfix-expression * postfix-expression
  ==>
      ...
  ==>
      6 - 2 * 3

the term 'operands' in 6.6p6 refers to '6', '2' and '3'.

[toc] | [prev] | [next] | [standalone]


#112604

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-06-19 13:45 -0400
Message-ID<97aef68d-40f4-f8ef-6167-f386abe06f2e@verizon.net>
In reply to#112603
On 06/19/2017 01:29 PM, Ike Naar wrote:
> On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
>> On 06/19/2017 11:51 AM, Ike Naar wrote:
>>> On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
>>>> On 06/19/2017 08:39 AM, David Brown wrote:
>>>>> I have now read the paragraph (6.6p6) a little better.  It does not
>>>>> limited the /operators/ used to make the "integer constant expression" -
>>>>> it limits the /operands/ used with operators.  So a conditional like
>>>>> this /can/ be an integer constant expression.
>>>>
>>>> While 0+0 is fine,  6-2*3 is not: the right operand of the subtraction
>>>> operator is a multiplication expression, which doesn't fall into any of
>>>> listed categories of allowed operands.
>>>
>>> According to the syntax, the right operand of the subtraction operator
>>> is always a multiplicative-expression.
>>
>> True, but not relevant, which I was trying to hint at by referring to it
>> as a "multiplication expression" (which isn't one of the standard-define
>> grammar terms), rather than "multiplicative-expression". As I'm using
>> the term, a "multiplicative expression" is one that actually has a
>> multiplication as it's operator.
>>
>> For comparison: 5 is a constant. As a result, it is also a
>> primary-expression, a postfix-expression, a unary-expression, and a
>> multiplicative-expression (assuming it occurs in a location where
>> expressions of one of those types are permitted by the grammar). But, as
>> a constant, 5 meets the requirements in 6.6p6 for an operand in an
>> integer constant expression. In contrast, the only one of those terms
>> that describes 2*3 is multiplicative-expression, and that's not enough
>> to qualify it for use in that context.
>
>   6.6
>   constant-expression
>     conditional-expression
>
>   6.6p6
>   An integer constant expression shall have integer type and
>   shall only have operands that are integer constants, [...]
>
> I take it that the term 'operands' in this sentence refers to the
> operands that appear in the full derivation of the constant-expression,
> that is, in the derivation
>
>       constant-expression
>   ==>
>       conditional-expression
>   ==>
>       ...
>   ==>
>       additive-expression
>   ==>
>       multiplicative-expression - multiplicative-expression
>   ==>
>       ...
>   ==>
>       postfix-expression - postfix-expression * postfix-expression
>   ==>
>       ...
>   ==>
>       6 - 2 * 3
>
> the term 'operands' in 6.6p6 refers to '6', '2' and '3'.

That would be another way of fixing this problem, equivalent to one 
which I've used internally for several years: 6.6p6 applies only to 
"leaf operands", that is, operands which are not themselves expressions 
with sub-expressions. However, while preparing my first message for this 
thread, I came to the conclusion that a recursive reference to integer 
constant expressions would be a cleaner way to fix this problem.

The point is, these ARE fixes. The wording as it is currently written 
doesn't provide any justification for applying 6.6p6 only to 
leaf-operands. As written, it applies to all operands, including those 
that are expressions with sub-expressions.

[toc] | [prev] | [next] | [standalone]


#112617

FromKeith Thompson <kst-u@mib.org>
Date2017-06-19 12:31 -0700
Message-ID<lnbmpjg4fp.fsf@kst-u.example.com>
In reply to#112604
"James R. Kuyper" <jameskuyper@verizon.net> writes:
> On 06/19/2017 01:29 PM, Ike Naar wrote:
>> On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
>>> On 06/19/2017 11:51 AM, Ike Naar wrote:
>>>> On 2017-06-19, James R. Kuyper <jameskuyper@verizon.net> wrote:
[...]
>>>>> While 0+0 is fine,  6-2*3 is not: the right operand of the subtraction
>>>>> operator is a multiplication expression, which doesn't fall into any of
>>>>> listed categories of allowed operands.
>>>>
>>>> According to the syntax, the right operand of the subtraction operator
>>>> is always a multiplicative-expression.
>>>
>>> True, but not relevant, which I was trying to hint at by referring to it
>>> as a "multiplication expression" (which isn't one of the standard-define
>>> grammar terms), rather than "multiplicative-expression". As I'm using
>>> the term, a "multiplicative expression" is one that actually has a
>>> multiplication as it's operator.
>>>
>>> For comparison: 5 is a constant. As a result, it is also a
>>> primary-expression, a postfix-expression, a unary-expression, and a
>>> multiplicative-expression (assuming it occurs in a location where
>>> expressions of one of those types are permitted by the grammar). But, as
>>> a constant, 5 meets the requirements in 6.6p6 for an operand in an
>>> integer constant expression. In contrast, the only one of those terms
>>> that describes 2*3 is multiplicative-expression, and that's not enough
>>> to qualify it for use in that context.
>>
>>   6.6
>>   constant-expression
>>     conditional-expression
>>
>>   6.6p6
>>   An integer constant expression shall have integer type and
>>   shall only have operands that are integer constants, [...]
>>
>> I take it that the term 'operands' in this sentence refers to the
>> operands that appear in the full derivation of the constant-expression,
>> that is, in the derivation
>>
[SNIP]
>>
>> the term 'operands' in 6.6p6 refers to '6', '2' and '3'.
>
> That would be another way of fixing this problem, equivalent to one 
> which I've used internally for several years: 6.6p6 applies only to 
> "leaf operands", that is, operands which are not themselves expressions 
> with sub-expressions. However, while preparing my first message for this 
> thread, I came to the conclusion that a recursive reference to integer 
> constant expressions would be a cleaner way to fix this problem.
>
> The point is, these ARE fixes. The wording as it is currently written 
> doesn't provide any justification for applying 6.6p6 only to 
> leaf-operands. As written, it applies to all operands, including those 
> that are expressions with sub-expressions.

And one item in the list of allowed "operands" is

    sizeof expressions whose results are integer constants

Given that sizeof is treated as an operator that takes an operand, it
can't be a leaf expression.

-- 
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]


#112579

FromIke Naar <ike@iceland.freeshell.org>
Date2017-06-19 15:10 +0000
Message-ID<slrn3vfsokfqhl.lnq.ike@iceland.freeshell.org>
In reply to#112557
On 2017-06-19, David Brown <david.brown@hesbynett.no> wrote:
> On 19/06/17 14:05, bartc wrote:
>> (a,b,0) can't be an integer constant expression, even if a and b are
>> constants, because the language considers that nonsensical.
>
> True.  I suspect that is because the comma operator has a sequence
> point, and it would not make sense to have a sequence point in a
> constant expression.

(0 || 0) is a null pointer constant that has a sequence point.

[toc] | [prev] | [next] | [standalone]


#112593

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-06-19 16:53 +0100
Message-ID<87shiwc4il.fsf@bsb.me.uk>
In reply to#112557
David Brown <david.brown@hesbynett.no> writes:

> On 19/06/17 14:05, bartc wrote:
>> On 19/06/2017 11:38, David Brown wrote:
>>> On 19/06/17 11:11, bartc wrote:
<snip>
>>>> 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).
>> 
>> (a,b,0) can't be an integer constant expression, even if a and b are
>> constants, because the language considers that nonsensical. 
>
> True.  I suspect that is because the comma operator has a sequence
> point, and it would not make sense to have a sequence point in a
> constant expression.

This is red-herring.  1 && 0 and 1 ? 0 : 0 are both constant expressions
and would have sequence points if there were ever evaluated at run-time.

> (For what it is worth, I am not a fan of the comma operator, and I am
> not keen on sequence points inside an expression other than an
> assignment.)

You are not keen on the short-cut semantics of && and ||?  I like them a
lot.

>> But I don't see why:
>> 
>>   p = (a,b,0);
>> 
>> can't be well-behaved. You evaluate a and b, then assign 0 to pointer p.
>> The language doesn't like it because implementing it is awkward (the
>> null-pointer-constant-ness of the terminal 0 doesn't propagate up in the
>> same way as the type of it would).
>
> No, the language does not like it because the sequence points spoil the
> special nature of the a pointer constant - there needs to be some rules
> to say when 0 is an int, and when it is a null pointer constant.

Sequence points have nothing to do with it.  For one thing, a sequence
point is a run-time notion.  But consider 1 && 0.  It is a valid null
pointer constant despite the sequence point.

Some syntactic forms are null pointer constants and some are not.  In
general, (a, b, 0) is not a null pointer constant because it is not an
integer constant expression but (1,2,0) is a null pointer constant.
Note that it would not be one without the ()s -- you need to check the
grammar to see why -- but I can't think of a way to check that compilers
get this right because all the obvious uses of comma expressions will
need ()s anyway.

gcc complains about using (1,0) as a null pointer constant but I don't
see what grounds it has for doing that.

> You can write:
>
> 	p = (a, b, (void*) 0);
>
> You can also write:
>
> 	p = (a, b, NULL);
>
> That is one of the purposes of having the NULL macro - it is /always/ a
> null pointer constant.

That makes no difference at all: NULL may always be a null pointer
constant but then so is 0.  What matters is the rest of the expression.
(int *)NULL is not a null pointer constant and (1,NULL) may or may not
be depending on how NULL is defined.

Your first example is now a valid assignment for other reasons, even if
a and b make the expression non-constant, and the second one will be
depending on how NULL is defined and the constant (or otherwise) nature
of a and b.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#112597

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-06-19 13:06 -0400
Message-ID<fb06cddb-0675-ca28-ec19-9a52cf7919e1@verizon.net>
In reply to#112593
On 06/19/2017 11:53 AM, Ben Bacarisse wrote:
...
> integer constant expression but (1,2,0) is a null pointer constant.

"Constant expressions shall not contain assignment, increment, 
decrement, function-call, or comma operators, except when they are 
contained within a subexpression that is not evaluated." (6.6p3).

[toc] | [prev] | [next] | [standalone]


#112609

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-06-19 20:03 +0100
Message-ID<87mv93dclh.fsf@bsb.me.uk>
In reply to#112597
"James R. Kuyper" <jameskuyper@verizon.net> writes:

> On 06/19/2017 11:53 AM, Ben Bacarisse wrote:
> ...
>> integer constant expression but (1,2,0) is a null pointer constant.
>
> "Constant expressions shall not contain assignment, increment,
> decrement, function-call, or comma operators, except when they are
> contained within a subexpression that is not evaluated." (6.6p3).

Missed that, thanks.  I was worried when gcc rejected it, since it is
not often wrong!

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#112630

FromDavid Brown <david.brown@hesbynett.no>
Date2017-06-19 22:37 +0200
Message-ID<oi9cf4$q9s$1@dont-email.me>
In reply to#112593
On 19/06/17 17:53, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
>> On 19/06/17 14:05, bartc wrote:
>>> On 19/06/2017 11:38, David Brown wrote:
>>>> On 19/06/17 11:11, bartc wrote:
> <snip>
>>>>> 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).
>>>
>>> (a,b,0) can't be an integer constant expression, even if a and b are
>>> constants, because the language considers that nonsensical.
>>
>> True.  I suspect that is because the comma operator has a sequence
>> point, and it would not make sense to have a sequence point in a
>> constant expression.
> 
> This is red-herring.  1 && 0 and 1 ? 0 : 0 are both constant expressions
> and would have sequence points if there were ever evaluated at run-time.
> 
>> (For what it is worth, I am not a fan of the comma operator, and I am
>> not keen on sequence points inside an expression other than an
>> assignment.)
> 
> You are not keen on the short-cut semantics of && and ||?  I like them a
> lot.

Sometimes they can provide the best (clearest) way to write code, with 
idiomatic expressions like "if (p && *p)...".  But in general, no, I 
prefer code to have the same effect and validity if && and || had been 
"normal" operators without short-cut semantics.  If two bits of code 
must be executed in a particular order for the program to be correct, I 
prefer to write them as separate statements on separate lines.  However, 
I am not rigid about these rules, and will bend them if I think the 
result is clearer code.

> 
>>> But I don't see why:
>>>
>>>    p = (a,b,0);
>>>
>>> can't be well-behaved. You evaluate a and b, then assign 0 to pointer p.
>>> The language doesn't like it because implementing it is awkward (the
>>> null-pointer-constant-ness of the terminal 0 doesn't propagate up in the
>>> same way as the type of it would).
>>
>> No, the language does not like it because the sequence points spoil the
>> special nature of the a pointer constant - there needs to be some rules
>> to say when 0 is an int, and when it is a null pointer constant.
> 
> Sequence points have nothing to do with it.  For one thing, a sequence
> point is a run-time notion.  But consider 1 && 0.  It is a valid null
> pointer constant despite the sequence point.

Fair enough.

> 
> Some syntactic forms are null pointer constants and some are not.  In
> general, (a, b, 0) is not a null pointer constant because it is not an
> integer constant expression but (1,2,0) is a null pointer constant.
> Note that it would not be one without the ()s -- you need to check the
> grammar to see why -- but I can't think of a way to check that compilers
> get this right because all the obvious uses of comma expressions will
> need ()s anyway.
> 
> gcc complains about using (1,0) as a null pointer constant but I don't
> see what grounds it has for doing that.
> 
>> You can write:
>>
>> 	p = (a, b, (void*) 0);
>>
>> You can also write:
>>
>> 	p = (a, b, NULL);
>>
>> That is one of the purposes of having the NULL macro - it is /always/ a
>> null pointer constant.
> 
> That makes no difference at all: NULL may always be a null pointer
> constant but then so is 0.  What matters is the rest of the expression.
> (int *)NULL is not a null pointer constant and (1,NULL) may or may not
> be depending on how NULL is defined.
> 
> Your first example is now a valid assignment for other reasons, even if
> a and b make the expression non-constant, and the second one will be
> depending on how NULL is defined and the constant (or otherwise) nature
> of a and b.
> 

Thanks for the explanations here.  I hope Bart can follow it!

My own knowledge here was enough for my own uses - if you never write 
"(a, b, 0)" then you don't need to know if it is a null pointer constant 
or not :-)

[toc] | [prev] | [next] | [standalone]


#112635

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-06-19 22:10 +0100
Message-ID<878tknd6ow.fsf@bsb.me.uk>
In reply to#112630
David Brown <david.brown@hesbynett.no> writes:

> On 19/06/17 17:53, Ben Bacarisse wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>
>>> On 19/06/17 14:05, bartc wrote:
>>>> On 19/06/2017 11:38, David Brown wrote:
>>>>> On 19/06/17 11:11, bartc wrote:
>> <snip>
>>>>>> 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).
>>>>
>>>> (a,b,0) can't be an integer constant expression, even if a and b are
>>>> constants, because the language considers that nonsensical.
>>>
>>> True.  I suspect that is because the comma operator has a sequence
>>> point, and it would not make sense to have a sequence point in a
>>> constant expression.
>>
>> This is red-herring.  1 && 0 and 1 ? 0 : 0 are both constant expressions
>> and would have sequence points if there were ever evaluated at run-time.
>>
>>> (For what it is worth, I am not a fan of the comma operator, and I am
>>> not keen on sequence points inside an expression other than an
>>> assignment.)
>>
>> You are not keen on the short-cut semantics of && and ||?  I like them a
>> lot.
>
> Sometimes they can provide the best (clearest) way to write code, with idiomatic expressions like "if (p && *p)...".  But in general, no, I prefer code to have the same effect and validity if && and || had been "normal" operators without short-cut semantics.  If two bits of code must be executed in a particular order for the program to be correct, I prefer to write them as separate statements on separate lines.  However, I am not rigid about these rules, and will bend them if I think the result is clearer code.
>
>>
>>>> But I don't see why:
>>>>
>>>>    p = (a,b,0);
>>>>
>>>> can't be well-behaved. You evaluate a and b, then assign 0 to pointer p.
>>>> The language doesn't like it because implementing it is awkward (the
>>>> null-pointer-constant-ness of the terminal 0 doesn't propagate up in the
>>>> same way as the type of it would).
>>>
>>> No, the language does not like it because the sequence points spoil the
>>> special nature of the a pointer constant - there needs to be some rules
>>> to say when 0 is an int, and when it is a null pointer constant.
>>
>> Sequence points have nothing to do with it.  For one thing, a sequence
>> point is a run-time notion.  But consider 1 && 0.  It is a valid null
>> pointer constant despite the sequence point.
>
> Fair enough.
>
>>
>> Some syntactic forms are null pointer constants and some are not.  In
>> general, (a, b, 0) is not a null pointer constant because it is not an
>> integer constant expression but (1,2,0) is a null pointer constant.
>> Note that it would not be one without the ()s -- you need to check the
>> grammar to see why -- but I can't think of a way to check that compilers
>> get this right because all the obvious uses of comma expressions will
>> need ()s anyway.
>>
>> gcc complains about using (1,0) as a null pointer constant but I don't
>> see what grounds it has for doing that.
>>
>>> You can write:
>>>
>>> 	p = (a, b, (void*) 0);
>>>
>>> You can also write:
>>>
>>> 	p = (a, b, NULL);
>>>
>>> That is one of the purposes of having the NULL macro - it is /always/ a
>>> null pointer constant.
>>
>> That makes no difference at all: NULL may always be a null pointer
>> constant but then so is 0.  What matters is the rest of the expression.
>> (int *)NULL is not a null pointer constant and (1,NULL) may or may not
>> be depending on how NULL is defined.
>>
>> Your first example is now a valid assignment for other reasons, even if
>> a and b make the expression non-constant, and the second one will be
>> depending on how NULL is defined and the constant (or otherwise) nature
>> of a and b.
>>
>
> Thanks for the explanations here.  I hope Bart can follow it!

Except that I'm wrong!  Comma operators are explicitly excluded along
with assignments, ++, -- and function calls.  (I'd remembered the latter
ones but had forgotten about commas.)

However, the notion that sequence points don't matter is right and I
could have correctly illustrated it with a ? 0 : 0.  Also, my point
about adding NULL or (void *)0 is also right (I hope).  In other words

  1 ? (void *)0 : (void *)0

is not a null pointer constant but will work in your example for the
other reasons I alluded to -- it's an expression of type void * and can
be convert to other object types such as that of p above.

To test this, try

  void (*p)(void);
  p = (1 ? (void *)0 : (void *)0);

You should get a diagnostic (gcc gives one) because a void * can't be
implicitly converted to a function pointer.  Had

  (1 ? (void *)0 : (void *)0)

been a null pointer constant, no diagnostic would be required.

> My own knowledge here was enough for my own uses - if you never write
> "(a, b, 0)" then you don't need to know if it is a null pointer
> constant or not :-)

Just avoid any confusion: it isn't -- ever.  It can't even be a constant
expression.  I should have been more careful.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#112638

FromKeith Thompson <kst-u@mib.org>
Date2017-06-19 14:25 -0700
Message-ID<lntw3bekkp.fsf@kst-u.example.com>
In reply to#112635
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> David Brown <david.brown@hesbynett.no> writes:
[...]
>> My own knowledge here was enough for my own uses - if you never write
>> "(a, b, 0)" then you don't need to know if it is a null pointer
>> constant or not :-)
>
> Just avoid any confusion: it isn't -- ever.  It can't even be a constant
> expression.  I should have been more careful.

Except that (6.6p10):
    An implementation may accept other forms of constant expressions.

-- 
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]


#112665

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-06-19 22:46 -0700
Message-ID<kfnwp876wj5.fsf@x-alumni2.alumni.caltech.edu>
In reply to#112638
Keith Thompson <kst-u@mib.org> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> David Brown <david.brown@hesbynett.no> writes:
>
> [...]
>
>>> My own knowledge here was enough for my own uses - if you never write
>>> "(a, b, 0)" then you don't need to know if it is a null pointer
>>> constant or not :-)
>>
>> Just avoid any confusion:  it isn't -- ever.  It can't even be a constant
>> expression.  I should have been more careful.
>
> Except that (6.6p10):
>     An implementation may accept other forms of constant expressions.

That's true, but it's sort of a moot point.  Using '(a, b, 0)' as a
constant expression requires a diagnostic (because a constraint has
been violated), and after giving a diagnostic the implementation
can do as it damn well pleases anyway.

[toc] | [prev] | [next] | [standalone]


#112694

FromKeith Thompson <kst-u@mib.org>
Date2017-06-20 08:43 -0700
Message-ID<lny3smd5qx.fsf@kst-u.example.com>
In reply to#112665
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>> David Brown <david.brown@hesbynett.no> writes:
>> [...]
>>
>>>> My own knowledge here was enough for my own uses - if you never write
>>>> "(a, b, 0)" then you don't need to know if it is a null pointer
>>>> constant or not :-)
>>>
>>> Just avoid any confusion:  it isn't -- ever.  It can't even be a constant
>>> expression.  I should have been more careful.
>>
>> Except that (6.6p10):
>>     An implementation may accept other forms of constant expressions.
>
> That's true, but it's sort of a moot point.  Using '(a, b, 0)' as a
> constant expression requires a diagnostic (because a constraint has
> been violated), and after giving a diagnostic the implementation
> can do as it damn well pleases anyway.

One could argue that the intent is that an implementation may
accept other forms of constant expression *without a diagnostic*.
If not, 6.6p10 "An implementation may accept other forms of
constant expressions."  would seem to be redundant, since it's
already covered by the permission to provide extensions.

If we follow what the standard actually says, the constraint in
paragraph 3 is uncondtional, and a diagnostic is required.

I'm not sure what the purpose of that added permission really is.
Do you know whether the authors had anything specific in mind?

-- 
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]


#112697

Fromsupercat@casperkitty.com
Date2017-06-20 09:17 -0700
Message-ID<6fdbb8e7-9142-440f-94d2-2a435cf75e2a@googlegroups.com>
In reply to#112694
On Tuesday, June 20, 2017 at 10:43:43 AM UTC-5, Keith Thompson wrote:
> I'm not sure what the purpose of that added permission really is.
> Do you know whether the authors had anything specific in mind?

One example I can imagine would be something like:

   unsigned char structHeaderBuff[offsetof(structType, someField)];

either using the official "offsetof()" or a similar pointer calculation.
Other examples might include calculations involving floating-point
intrinsics.  The fact that the permission for additional forms is not
in the constraints section would seem to suggest that a diagnostic should
be required in cases involving the comma operator, though an implementation
could say e.g. that an expression of the form (x) is an Integer Constant
Expression if x is either an integer constant expression, or is a comma
expression whose first operand has no side-effects and whose second
operand is an ICE.

[toc] | [prev] | [next] | [standalone]


#112757

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-06-21 00:56 -0700
Message-ID<kfny3sl6afc.fsf@x-alumni2.alumni.caltech.edu>
In reply to#112694
Keith Thompson <kst-u@mib.org> writes:

> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> Keith Thompson <kst-u@mib.org> writes:
>>
>>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>>
>>>> David Brown <david.brown@hesbynett.no> writes:
>>>
>>> [...]
>>>
>>>>> My own knowledge here was enough for my own uses - if you never write
>>>>> "(a, b, 0)" then you don't need to know if it is a null pointer
>>>>> constant or not :-)
>>>>
>>>> Just avoid any confusion:  it isn't -- ever.  It can't even be a constant
>>>> expression.  I should have been more careful.
>>>
>>> Except that (6.6p10):
>>>     An implementation may accept other forms of constant expressions.
>>
>> That's true, but it's sort of a moot point.  Using '(a, b, 0)' as a
>> constant expression requires a diagnostic (because a constraint has
>> been violated), and after giving a diagnostic the implementation
>> can do as it damn well pleases anyway.
>
> One could argue that the intent is that an implementation may
> accept other forms of constant expression *without a diagnostic*.

I agree;  one could so argue.  I think it would be hard to
make the argument convincing, but certainly one could be made.

> If not, 6.6p10 "An implementation may accept other forms of
> constant expressions." would seem to be redundant, since it's
> already covered by the permission to provide extensions.

I don't think 6.6 p10 is redundant, because only some of the
restrictions on various forms of constant expressions are
constraints.  In 6.6 p6, for example, there are restrictions
on integer constant expressions that are not constraints.
The allowance in 6.6 p10 could be used to establish other
forms of integer constant expressions but which still did
not violate the constraints in 6.6 p3.

> If we follow what the standard actually says, the constraint in
> paragraph 3 is uncondtional, and a diagnostic is required.

I consider the term "constant expression" to be defined by the
syntax rule in 6.6 p1 and the property stated in 6.6 p2.  Seen in
this light, an expression like '(0,0)' is a constant expression,
but just one that violates a constraint, and so must be given a
diagnostic.  In times past I viewed the constraints in 6.6 p3 as
definitional, but I no longer view them that way.

(Let me add that this is pretty much just splitting hairs,
because either view results in a diagnostic being required, and
diagnostics can say whatever they want.  I think though it's
useful to present the distinction, split hairs notwithstanding.)

> I'm not sure what the purpose of that added permission really is.
> Do you know whether the authors had anything specific in mind?

How about this:  The intent of 6.6 p10 is to allow an
implementation to accept syntactic forms, such as might be
generated by the offsetof macro, that may not otherwise be
semantically allowed.

(I have to admit I cheated by reading DR 032 before giving my
answer.)

[toc] | [prev] | [next] | [standalone]


#112808

FromKeith Thompson <kst-u@mib.org>
Date2017-06-21 10:07 -0700
Message-ID<ln1sqdclr8.fsf@kst-u.example.com>
In reply to#112757
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
[...]
>> One could argue that the intent is that an implementation may
>> accept other forms of constant expression *without a diagnostic*.
>
> I agree;  one could so argue.  I think it would be hard to
> make the argument convincing, but certainly one could be made.
>
>> If not, 6.6p10 "An implementation may accept other forms of
>> constant expressions." would seem to be redundant, since it's
>> already covered by the permission to provide extensions.
>
> I don't think 6.6 p10 is redundant, because only some of the
> restrictions on various forms of constant expressions are
> constraints.  In 6.6 p6, for example, there are restrictions
> on integer constant expressions that are not constraints.
> The allowance in 6.6 p10 could be used to establish other
> forms of integer constant expressions but which still did
> not violate the constraints in 6.6 p3.

Hmm.  Straying a bit into more quibbling, 6.6p6, defining "integer
constant expression", uses the word "shall" repeatedly:

    An *integer constant expression* shall have integer type and shall
    only have operands that are integer constants, ...

The standard defines what it means by "shall" (4p1-2), and since
6.6p6 is not a constraint it implies that violating it causes
undefined behavior.  Which would mean that `case 0.0:` does not
require a diagnostic, but does have undefined behavior.

I don't think that was the intent.  Rather I think the intent is
that 0.0 *is not* an integer constant expression, and using it
in a case label violates the constraint that the expression shall
be an integer constant expression (6.8.4.2p3).  I suggest that the
restrictions in 6.6p6 should be considered part of the definition of
"integer constant expression", and should not be stated using the
word "shall".

Summary: English is hard.

[...]

>> I'm not sure what the purpose of that added permission really is.
>> Do you know whether the authors had anything specific in mind?
>
> How about this:  The intent of 6.6 p10 is to allow an
> implementation to accept syntactic forms, such as might be
> generated by the offsetof macro, that may not otherwise be
> semantically allowed.
>
> (I have to admit I cheated by reading DR 032 before giving my
> answer.)

http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_032.html

-- 
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]


Page 2 of 6 — ← Prev page 1 [2] 3 4 5 6  Next page →

Back to top | Article view | comp.lang.c


csiph-web