Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Null pointer constant Date: Mon, 19 Jun 2017 10:15:36 -0700 Organization: None to speak of Lines: 127 Message-ID: References: <9zM1B.193976$KK7.183000@fx12.am4> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="6cbb5d51c319bdfdc6c4f737cfea8267"; logging-data="23646"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/EzGy6SwiXzDU4UmPx/q9l" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:oqPDRXRwWQT6Hk/GFXiTz0wGcxc= sha1:mazyob7O04z5LdNydkwAQF+Z0mk= Xref: csiph.com comp.lang.c:112598 David Brown writes: > 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. Correction: It can be a constant expression, provided a, b, and c are constant expressions. (I'm assuming a, b, and c are intended to represent arbitrary subexpressions and needn't be just identifiers.) Apart from that quibble, bartc's statement is correct. >>> 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? David, your previous followup seemed to imply that a conditional expression cannot be an integer constant expression. In fact it can; for example `1?0:0` is both an integer constant expression and a null pointer constant. But a conditional expression can be a constant expression only if all three of its operands are constant expressions. >>>> 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. Note that a constant expression cannot contain a comma operator. > 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. David, I think you're missing something. A *null pointer constant* is a kind of expression, but it's not necessarily of pointer type, and it's not necessarily a constant. (Remember that a constant, as opposed to a constant expression, is a single token.) 0 is a null pointer constant of type int. It can be explicitly or implicitly *converted* to a pointer type, yielding a null pointer. Given that `a` is the name of an object, the expression `a ? 0 : 0` is not a constant expression, and therefore not an integer constant expression, and therefore not a null pointer constant. But the second and third operands, both of which are simply `0`, are: constants integer constants octal constants constant expressions integer constant expressions null pointer constants expressions of type int `0` is of type int, and is a null pointer constant. `1 ? 0 : 0` is of type int, and is a null pointer constant. `a ? 0 : 0` is of type int, and is *not* a null pointer constant. [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org 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"