Topic: Defect Report: String Literal in #if


Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Mon, 5 Aug 2002 04:42:23 GMT
Raw View
"Martin v. L   wis" <loewis@informatik.hu-berlin.de> wrote in message
news:j43ctustzd.fsf@aramis.informatik.hu-berlin.de...
> "Paul Mensonides" <pmenso57@attbi.com> writes:
>
> > This is true except that you can't use a few things--e.g. casts.
>
> Right. There are many reasons for this; the primary reason is that you
> cannot name the target type of the cast (as the type name gets
> replaced with 0 prior to evaluation).

Yes, and the use of casts would complicate the parser of the preprocessor.

> > This is true also.  For instance, if you are using a compiler where long is
> > 32-bits:
> >
> > #define TWO_BILLION 2000000000
> >
> > #if (TWO_BILLION * 2) // <-- error, overflow
> >
> > #if (TWO_BILLION * 2UL) // <-- okay with promotion
>
> I think C99 changes this: it does preprocessor arithmetic in
> intmax_t/uintmax_t.

The point was that they are typed literals.  Even __STDC_VERSION__ expands to a
typed literal in C99:  199901L

> > Yes.  Also note that any identifier that is not defined and not a keyword is
> > replaced by zero also.
>
> Keywords are also replaced. Only "true" and "false" are excempt from
> being replaced; the "alternative tokens" are also not replaced.

Yeah, I misread it.

> > A string literal, regardless of whether it is considered as a
> > "string literal" or an array of characters, is not a constant
> > expression.
>
> Can you quote chapter and verse that says so? 5.19/1 clearly says that
> a string literal is a constant expression (since it is a literal).

Well, 16.1/4 refers to 5.19.  The introductory sentence states "In several
places, C++ requires expressions that evaluate to an integral or enumeration
constant: ..."

A string literal does not evaluate to a integral or enumeration constant.

It also says that only type conversions to integral or enumeration types can be
used and that you can't use pointers.  The only way that a string literal can
become an integral constant is if it is implicitly converted to a pointer which
is then implicitly converted to 0 or 1.  Pointers are explicitly prohibited from
appearing in constant expressions, therefore string literals are not allowed.

I agree that this is not exactly clear, but nevertheless it is there IMO.

> > The standard clearly states that the evaluation performed in
> > #if/#elif directives is exactly like constant expressions with a few
> > limitations.  Namely, it cannot include casts, and it can include
> > 'defined'.
>
> The exclusion of casts seems to be another defect (but a minor one):
> You cannot write a cast even if you would allow it, since all keywords
> and type identifiers get replaced with 0.

The lack of casts doesn't bother me.  It also cannot evaluate any other normal
C++ construct (such as template metafunctions).  Also, you can already get
limited upward promotion:

X * 1UL

Regardless of what type 'X' is, the result will be "unsigned long" of the same
value.

Paul Mensonides


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loewis@informatik.hu-berlin.de (Martin v. =?iso-8859-1?q?L=F6wis?=)
Date: Mon, 5 Aug 2002 16:19:55 GMT
Raw View
"Paul Mensonides" <pmenso57@attbi.com> writes:

> > Can you quote chapter and verse that says so? 5.19/1 clearly says that
> > a string literal is a constant expression (since it is a literal).
>
> Well, 16.1/4 refers to 5.19.  The introductory sentence states "In
> several places, C++ requires expressions that evaluate to an
> integral or enumeration constant: ..."

It is clearly the intent of the standard that the text that follows
below specifies such expressions. The defect I report is that it
actually doesn't.

> A string literal does not evaluate to a integral or enumeration
> constant.

5.19/1 does not even list the preprocessor as a context where an
integral or enumeration constant is required.

Also notice that the term "integral or enumeration constant" is not
formally defined - it is precisely the job of this section to define
similar terms (constant-expression, integral constant-expression, and
others).

For all I can tell, a string literal *is* an "integral or enumeration
constant" - because it is an "integral constant-expression".

You seem to assume the definition "an integral or enumeration constant
is a constant expression of integral or enumeration type".

However, the standard does not give this definition. It could be just
as reasonably defined as "in integral or enumeration constant is an
integral constant-expression".

> It also says that only type conversions to integral or enumeration
> types can be used and that you can't use pointers.

Right. However,

#if "Hallo"

does not involve any type conversions, nor does it use pointers.

> The only way that a string literal can become an integral constant
> is if it is implicitly converted to a pointer which is then
> implicitly converted to 0 or 1.

I don't know what an "integral constant" is. However, a string literal
is an "integral constant-expression" - there is no need to become one
by conversion.

> > The exclusion of casts seems to be another defect (but a minor one):
> > You cannot write a cast even if you would allow it, since all keywords
> > and type identifiers get replaced with 0.
>
> The lack of casts doesn't bother me.

It does not bother me, either. What bothers me is that the authors of
the text apparently saw a need to explicitly ban casts - according to
my understanding, that ban is not needed, since you can't write a cast
in the first place.

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loewis@informatik.hu-berlin.de (Martin v. =?iso-8859-15?q?L=F6wis?=)
Date: Mon, 5 Aug 2002 21:07:42 GMT
Raw View
Gennaro Prota <gennaro_prota@yahoo.com> writes:

> "An integral constant-expression can involve only literals (2.13),
> enumerators, const variables or static data members of integral or
> enumeration types initialized with constant expressions (8.5),
> non-type template parameters of integral or enumeration types, and
> sizeof expressions. Floating literals (2.13.3) can appear only if they
> are cast to integral or enumeration types. [insertion: String literals
> can never appear.]"
>
>
> I don't see anything preprocessing specific here, but my impression is
> that others do.

The question is whether

   sizeof("Hallo")

ought to be a constant-expression. It is truly constant and
well-defined (it evaluates to 6), so people might want this.

In the preprocessor, this won't work, though - sizeof is replaced by
0, so this would read 0("Hallo"), which is ill-formed.

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Mon, 5 Aug 2002 17:19:04 CST
Raw View
On Mon,  5 Aug 2002 21:07:42 GMT, loewis@informatik.hu-berlin.de
(Martin v. L   wis) wrote:

>Gennaro Prota <gennaro_prota@yahoo.com> writes:
>
>> "An integral constant-expression can involve only literals (2.13),
>> enumerators, const variables or static data members of integral or
>> enumeration types initialized with constant expressions (8.5),
>> non-type template parameters of integral or enumeration types, and
>> sizeof expressions. Floating literals (2.13.3) can appear only if they
>> are cast to integral or enumeration types. [insertion: String literals
>> can never appear.]"
>>
>>
>> I don't see anything preprocessing specific here, but my impression is
>> that others do.
>
>The question is whether
>
>   sizeof("Hallo")
>
>ought to be a constant-expression.


Ok. But is there any context outside the preprocessor where you would
put a non sized-of string-literal and expect the expression to be an
integral constant expression? If not, a change to 5.19/1 would still
be required. For instance:

"In particular, except in sizeof expressions, functions, class
objects, pointers, [insert: string-literals] or references shall not
be used, and assignment, increment, decrement, function-call, or comma
operators shall not be used."

Actually, I don't like mixing expressions (string-literals) with all
the other things (functions, objects, etc.) that are there so consider
the above just a quick  way to clarify my point.

In the preprocessor, this wouldn't affect the use of sizeof("Hello")
because replacement of 'sizeof' with 0 makes it automatically
ill-formed as it already is and would make a raw (without sizeof) use
of a string-literal like

#if "Hello"

ill-formed because the controlling expression is not an integral
constant expression.

Again, I see it as a problem (if there's a problem) of 5.19. But this
evening the temperature in my room is really too high! :-)


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loewis@informatik.hu-berlin.de (Martin v. =?iso-8859-15?q?L=F6wis?=)
Date: Fri, 2 Aug 2002 15:50:19 GMT
Raw View
kanze@gabi-soft.de (James Kanze) writes:

> Of course, your example was in the preprocessor, where somewhat
> different rules apply.  The conversion, or even the decay, do not occur
> until a much later phase; for that matter, in the preprocessor, "Hello,
> world" is a string literal, and not a char[13] (which doesn't exist in
> the context of the preprocessor).

16.1/4 says that the preprocessor evaluates the expression according
to the rules of 5.19, except that int and long have the same
representation.

> The preprocessor uses typeless integral arithmetic when evaluating
> expressions.

I don't think this is true. Instead, the preprocessor evaluates
expressions in the same way that integral constant expressions are
evaluated elsewhere (including integral promotions, and everything).

> (It doesn't have a bool type either, and "true" and "false" only
> work in preprocessor expressions because of a special rule which
> converts them to the strings "1" and "0" respectively.)

I don't think this is true, either. 16.1/4 are explicitly mentions
that true and false are *not* replaced with an integer
literal. Instead,

"Each subexpression with type bool is subjected to integral promotion
before processing continues."

So there appears to be a bool type in the preprocessor.

> Your question was perfectly valid.  I was only picking a nit with the
> statement that "Hello, world" was neither true nor false.

I understand that. I still sense a different understanding between you
and me on how exactly the preprocessor works, and I'd like to clear
that up. As usual, I'm not at all convinced that my interpretation is
correct, I just try to phrase it so that readers will likely spot
errors in my thinking.

Kind regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Sat, 3 Aug 2002 00:07:00 GMT
Raw View
"Martin v. L   wis" <loewis@informatik.hu-berlin.de> wrote in message
news:j47kj9635u.fsf@aramis.informatik.hu-berlin.de...

> 16.1/4 says that the preprocessor evaluates the expression according
> to the rules of 5.19, except that int and long have the same
> representation.

This is true except that you can't use a few things--e.g. casts.

> > The preprocessor uses typeless integral arithmetic when evaluating
> > expressions.
>
> I don't think this is true. Instead, the preprocessor evaluates
> expressions in the same way that integral constant expressions are
> evaluated elsewhere (including integral promotions, and everything).

This is true also.  For instance, if you are using a compiler where long is
32-bits:

#define TWO_BILLION 2000000000

#if (TWO_BILLION * 2) // <-- error, overflow

#if (TWO_BILLION * 2UL) // <-- okay with promotion

> > (It doesn't have a bool type either, and "true" and "false" only
> > work in preprocessor expressions because of a special rule which
> > converts them to the strings "1" and "0" respectively.)
>
> I don't think this is true, either. 16.1/4 are explicitly mentions
> that true and false are *not* replaced with an integer
> literal. Instead,
>
> "Each subexpression with type bool is subjected to integral promotion
> before processing continues."
>
> So there appears to be a bool type in the preprocessor.

Yes.  Also note that any identifier that is not defined and not a keyword is
replaced by zero also.

> > Your question was perfectly valid.  I was only picking a nit with the
> > statement that "Hello, world" was neither true nor false.
>
> I understand that. I still sense a different understanding between you
> and me on how exactly the preprocessor works, and I'd like to clear
> that up. As usual, I'm not at all convinced that my interpretation is
> correct, I just try to phrase it so that readers will likely spot
> errors in my thinking.

A string literal, regardless of whether it is considered as a "string literal" o
r an array of characters, is not a constant expression.  The standard clearly
states that the evaluation performed in #if/#elif directives is exactly like
constant expressions with a few limitations.  Namely, it cannot include casts,
and it can include 'defined'.

Paul Mensonides


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Sat, 3 Aug 2002 19:05:02 GMT
Raw View
On Wed, 31 Jul 2002 15:03:57 GMT, loewis@informatik.hu-berlin.de
(Martin v. L=F6wis) wrote:

>Gennaro Prota <gennaro_prota@yahoo.com> writes:
>
>> >5.19 ([expr.const]/1) says that an integral constant expression may
>> >involve literals
>>=20
>> Well, I've always read that section thinking that the phrase "of
>> integral or enumeration types" referred to literals too, though a
>> literal of integral or enumeration type turns out to be a literal of
>> integral type :-). But a closer look (in particular at the punctuation
>> used) shows that the phrase is part of a longer one that also talks
>> about initialization and thus cannot refer to literals.
>
>Indeed. Grouping of English sentences is tricky, but I get the same
>reading.
>
>> // just kidding!
>> //
>> switch (a) {
>>    case "hello":
>>    break;
>>=20
>>    case "world":
>>    break;
>> }
>
>I would have assumed that 6.4.2 requires an integral constant
>expression of integral or enumeration type, but indeed it doesn't.
>

It says that the constant-expression in

  case   constant-expression :

shall be an integral constant-expression, which would be what you (we)
assumed if the definition of 'integral constant-expression' didn't
(accidentally, I hope) include string-literals too.


>However, 6.4.2 says that the expression is implicitly converted to the
>promoted type of the switch expression. This conversion fails, so this
>example would be ill-formed

Agreed :-)


>(but I agree that banning string literals
>from integral constant expressions is probably a good thing).


Frankly the wording of 5.19/1 seems *the* problem to me. I have never
thought that an integral constant expression could involve a string
literal. If I had submitted the defect report I would have simply
suggested to change it as follows:


"An integral constant-expression can involve only literals (2.13),
enumerators, const variables or static data members of integral or
enumeration types initialized with constant expressions (8.5),
non-type template parameters of integral or enumeration types, and
sizeof expressions. Floating literals (2.13.3) can appear only if they
are cast to integral or enumeration types. [insertion: String literals
can never appear.]"


I don't see anything preprocessing specific here, but my impression is
that others do.


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loewis@informatik.hu-berlin.de (Martin v. =?iso-8859-15?q?L=F6wis?=)
Date: Mon, 5 Aug 2002 02:23:03 GMT
Raw View
"Paul Mensonides" <pmenso57@attbi.com> writes:

> This is true except that you can't use a few things--e.g. casts.

Right. There are many reasons for this; the primary reason is that you
cannot name the target type of the cast (as the type name gets
replaced with 0 prior to evaluation).

> This is true also.  For instance, if you are using a compiler where long is
> 32-bits:
>
> #define TWO_BILLION 2000000000
>
> #if (TWO_BILLION * 2) // <-- error, overflow
>
> #if (TWO_BILLION * 2UL) // <-- okay with promotion

I think C99 changes this: it does preprocessor arithmetic in
intmax_t/uintmax_t.

> Yes.  Also note that any identifier that is not defined and not a keyword is
> replaced by zero also.

Keywords are also replaced. Only "true" and "false" are excempt from
being replaced; the "alternative tokens" are also not replaced.

> A string literal, regardless of whether it is considered as a
> "string literal" o r an array of characters, is not a constant
> expression.

Can you quote chapter and verse that says so? 5.19/1 clearly says that
a string literal is a constant expression (since it is a literal).

> The standard clearly states that the evaluation performed in
> #if/#elif directives is exactly like constant expressions with a few
> limitations.  Namely, it cannot include casts, and it can include
> 'defined'.

The exclusion of casts seems to be another defect (but a minor one):
You cannot write a cast even if you would allow it, since all keywords
and type identifiers get replaced with 0.

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.de (James Kanze)
Date: Tue, 30 Jul 2002 15:58:56 GMT
Raw View
loewis@informatik.hu-berlin.de (Martin v. L   wis wrote in message
news:<j44reih422.fsf@aramis.informatik.hu-berlin.de>...

> [ moderator's note: Forwarded to C++ Committee. -sdc ]

> According to 16.1 ([cpp.cond]/1), the if-group

> #if "Hello, world"

> is well-formed, since it is an integral constant expression.  Since
> that may not be obvious, here is why:

> 5.19 ([expr.const]/1) says that an integral constant expression may
> involve literals (2.13); "Hello, world" is a literal. It restricts
> operators to not use certain type conversions; this expression does
> not use type conversions. It further disallows functions, class
> objects, pointers, ... - this expression is none of those, since it is
> an array.

> However, 16.1/6 does not explain what to do with this if-group, since
> the expression evaluates neither to false(zero) nor true(non-zero).

Within a program, the expression "Hello, world" evaluates to true.
(Pointer to bool conversion takes place, the the results can't be a null
pointer.)

I still agree with you that it should be banned in this context.

--
James Kanze                           mailto:jkanze@caicheuvreux.com
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Wed, 31 Jul 2002 06:30:56 CST
Raw View
On 29 Jul 2002 17:13:12 GMT, loewis@informatik.hu-berlin.de (Martin v.
L   wis) wrote:

>
>[ moderator's note: Forwarded to C++ Committee. -sdc ]
>
>According to 16.1 ([cpp.cond]/1), the if-group
>
>#if "Hello, world"
>
>is well-formed, since it is an integral constant expression.

Uh??

>Since that may not be obvious, here is why:
>
>5.19 ([expr.const]/1) says that an integral constant expression may
>involve literals

Well, I've always read that section thinking that the phrase "of
integral or enumeration types" referred to literals too, though a
literal of integral or enumeration type turns out to be a literal of
integral type :-). But a closer look (in particular at the punctuation
used) shows that the phrase is part of a longer one that also talks
about initialization and thus cannot refer to literals.

So this is a case where I read into the standard what I thought there
was, instead of what there is :-) Fortunately implementers read it
this way too. Consider that this is not specifically a preprocessing
problem!


// just kidding!
//
switch (a) {
   case "hello":
   break;

   case "world":
   break;
}


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loewis@informatik.hu-berlin.de (Martin v. =?iso-8859-15?q?L=F6wis?=)
Date: Wed, 31 Jul 2002 15:03:36 GMT
Raw View
kanze@gabi-soft.de (James Kanze) writes:

> Within a program, the expression "Hello, world" evaluates to true.

That is not strictly true: The expression "Hello, world" can be
*converted* to true. It evaluates to a char[13] array.

> (Pointer to bool conversion takes place, the the results can't be a null
> pointer.)

In an expression, only array-to-pointer conversion take place
automatically, no? The integral promotions take place also, but won't
touch pointers. So it decays to const char* on its own.

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loewis@informatik.hu-berlin.de (Martin v. =?iso-8859-15?q?L=F6wis?=)
Date: Wed, 31 Jul 2002 15:03:57 GMT
Raw View
Gennaro Prota <gennaro_prota@yahoo.com> writes:

> >5.19 ([expr.const]/1) says that an integral constant expression may
> >involve literals
>
> Well, I've always read that section thinking that the phrase "of
> integral or enumeration types" referred to literals too, though a
> literal of integral or enumeration type turns out to be a literal of
> integral type :-). But a closer look (in particular at the punctuation
> used) shows that the phrase is part of a longer one that also talks
> about initialization and thus cannot refer to literals.

Indeed. Grouping of English sentences is tricky, but I get the same
reading.

> // just kidding!
> //
> switch (a) {
>    case "hello":
>    break;
>
>    case "world":
>    break;
> }

I would have assumed that 6.4.2 requires an integral constant
expression of integral or enumeration type, but indeed it doesn't.

However, 6.4.2 says that the expression is implicitly converted to the
promoted type of the switch expression. This conversion fails, so this
example would be ill-formed (but I agree that banning string literals
from integral constant expressions is probably a good thing).

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kanze@gabi-soft.de (James Kanze)
Date: Thu, 1 Aug 2002 17:57:43 GMT
Raw View
loewis@informatik.hu-berlin.de (Martin v. L   wis wrote in message
news:<j4heigezsd.fsf@aramis.informatik.hu-berlin.de>...
> kanze@gabi-soft.de (James Kanze) writes:

> > Within a program, the expression "Hello, world" evaluates to true.

> That is not strictly true: The expression "Hello, world" can be
> *converted* to true. It evaluates to a char[13] array.

Correct.  I elided a number of intermediate steps.

> > (Pointer to bool conversion takes place, the the results can't be a
> > null pointer.)

> In an expression, only array-to-pointer conversion take place
> automatically, no? The integral promotions take place also, but won't
> touch pointers. So it decays to const char* on its own.

Actually, there are contexts where it doesn't even decay to const char*.

In this case, I was thinking very definitly of a context where a boolean
value was needed.  In this case, it decays to char const*, and the char
const* converts to bool.

Of course, your example was in the preprocessor, where somewhat
different rules apply.  The conversion, or even the decay, do not occur
until a much later phase; for that matter, in the preprocessor, "Hello,
world" is a string literal, and not a char[13] (which doesn't exist in
the context of the preprocessor).  The preprocessor uses typeless
integral arithmetic when evaluating expressions.  (It doesn't have a
bool type either, and "true" and "false" only work in preprocessor
expressions because of a special rule which converts them to the strings
"1" and "0" respectively.)

Your question was perfectly valid.  I was only picking a nit with the
statement that "Hello, world" was neither true nor false.

--
James Kanze                           mailto:jkanze@caicheuvreux.com
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: loewis@informatik.hu-berlin.de (Martin v. =?iso-8859-15?q?L=F6wis?=)
Date: 29 Jul 2002 17:13:12 GMT
Raw View
[ moderator's note: Forwarded to C++ Committee. -sdc ]

According to 16.1 ([cpp.cond]/1), the if-group

#if "Hello, world"

is well-formed, since it is an integral constant expression.
Since that may not be obvious, here is why:

5.19 ([expr.const]/1) says that an integral constant expression may
involve literals (2.13); "Hello, world" is a literal. It restricts
operators to not use certain type conversions; this expression does
not use type conversions. It further disallows functions, class
objects, pointers, ... - this expression is none of those, since it is
an array.

However, 16.1/6 does not explain what to do with this if-group, since
the expression evaluates neither to false(zero) nor true(non-zero).

Regards,
Martin



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]