Macro constants

I

Ioannis Vranos

==> C90:


Errata for K&R2 page 232 (from
http://www-db-out.research.bell-labs.com/cm/cs/cbook/2ediffs.html):\


232(§A12.5): The result of the defined operator is not replaced
literally by 0L or 1L, nor are undefined names literally by 0L, but just
by plain 0 or 1. However, the constant expression is nevertheless
evaluated as if these and *other constants* appearing have long or
unsigned long type.


When it mentions "these and other constants", what are the other
constants implied?
 
T

Thad Smith

Ioannis said:
Errata for K&R2 page 232 (from
http://www-db-out.research.bell-labs.com/cm/cs/cbook/2ediffs.html):\


232(§A12.5): The result of the defined operator is not replaced
literally by 0L or 1L, nor are undefined names literally by 0L, but just
by plain 0 or 1. However, the constant expression is nevertheless
evaluated as if these and *other constants* appearing have long or
unsigned long type.


When it mentions "these and other constants", what are the other
constants implied?

That would certainly include the user literals, such as 2 in

#if X > 2
 
I

Ioannis Vranos

Thad said:
That would certainly include the user literals, such as 2 in

#if X > 2


So when

#define SOMETHING 6

is used, the 6 is considered as long or unsigned long?



Also I can't understand the following sentence completely:


"However, the constant expression"

I suppose it means the expression


defined identifier

or

defined ( identifier)



"is nevertheless evaluated as if these and other constants"


Which constants does it mean with "these", and which constants does it
mean with "other"?


"appearing have long or unsigned long type".
 
W

Walter Roberson

Ioannis Vranos said:
Also I can't understand the following sentence completely:
"However, the constant expression"
I suppose it means the expression
defined identifier

defined ( identifier)
Yes.


"is nevertheless evaluated as if these and other constants"
Which constants does it mean with "these",

The 0 or 1 that results from evaluating the 'defined' operator.
and which constants does it
mean with "other"?

User literal numbers, macros that expand to user literal numbers.
"appearing have long or unsigned long type".

If a literal constant without a suffix is greater than LONG_MAX then it
will be treated as unsigned. I believe everything else follows from the
usual promotion rules for mixing signed and unsigned values -- so if you
add two large unsuffixed numeric literals each less than LONG_MAX,
that would be a signed operation, with overflow a possibility
I believe (it is a constraint violation to evaluate to something
that is outside the representable range for the type, due to
the #if processing of constant expressions to be done the same way
as for constant expressions in normal text, and the appropriate
section of the standard for that has a "shall" clause requiring
keeping within the representable range.)
 
I

Ioannis Vranos

Walter said:
The 0 or 1 that results from evaluating the 'defined' operator.


User literal numbers, macros that expand to user literal numbers.


If a literal constant without a suffix is greater than LONG_MAX then it
will be treated as unsigned. I believe everything else follows from the
usual promotion rules for mixing signed and unsigned values -- so if you
add two large unsuffixed numeric literals each less than LONG_MAX,
that would be a signed operation, with overflow a possibility
I believe (it is a constraint violation to evaluate to something
that is outside the representable range for the type, due to
the #if processing of constant expressions to be done the same way
as for constant expressions in normal text, and the appropriate
section of the standard for that has a "shall" clause requiring
keeping within the representable range.)


I didn't understand the above. User literal integer numbers without a
suffix are considered as ints.


The text mentions that "However, the constant expression is nevertheless
evaluated as if these and other constants appearing have long or
unsigned long type", not int or unsigned int.


I suppose it means that when we have:


#define WHATEVER 123


#if defined (WHATEVER)


in defined statement, the WHATEVER is considered as long or unsigned
long, but I am not sure if this is what it means.
 
B

Ben Bacarisse

Ioannis Vranos said:
User literal integer numbers without a
suffix are considered as ints.

The text mentions that "However, the constant expression is nevertheless
evaluated as if these and other constants appearing have long or
unsigned long type", not int or unsigned int.

I suppose it means that when we have:

#define WHATEVER 123

#if defined (WHATEVER)

in defined statement, the WHATEVER is considered as long or unsigned
long, but I am not sure if this is what it means.

No, it is talking about two things:

(1) the replacement of defined(WHATEVER) by 1
(2) any other constants that might be there.

When WHATEVER appears *on its own* in an #if expression it will be
replaced by 123 and *that* constant will be considered to be long, but
the text you quote is talking about defined(WHATEVER). The whole
defined(WHATEVER) is replaced by 1 and it is that 1 that is considered
to be long, not int.

In this example:

#if defined(WHATEVER) + defined(NOT_DEFINED_ANYWHERE) + 32 + WHATEVER

there are three substitutions:

defined(WHATEVER) => 1
defined(NOT_DEFINED_ANYWHERE) => 0
WHATEVER => 123

and one "other constant" 32. All of these are to be considered as
having long or unsigned long type.
 
I

Ioannis Vranos

Ben said:
No, it is talking about two things:

(1) the replacement of defined(WHATEVER) by 1
(2) any other constants that might be there.

When WHATEVER appears *on its own* in an #if expression it will be
replaced by 123 and *that* constant will be considered to be long, but
the text you quote is talking about defined(WHATEVER). The whole
defined(WHATEVER) is replaced by 1 and it is that 1 that is considered
to be long, not int.

In this example:

#if defined(WHATEVER) + defined(NOT_DEFINED_ANYWHERE) + 32 + WHATEVER

there are three substitutions:

defined(WHATEVER) => 1
defined(NOT_DEFINED_ANYWHERE) => 0
WHATEVER => 123

and one "other constant" 32. All of these are to be considered as
having long or unsigned long type.


In the #define SOMETHING 123 case, 123 is considered int or long where
it substitutes SOMETHING, like in

int array[SOMETHING]; ?
 
H

Hallvard B Furuseth

Ioannis said:
So when
#define SOMETHING 6
is used, the 6 is considered as long or unsigned long?

In preprocessor arithmetic in C89, yes. 6 is considered long since it
fits in a long. 4000000000 does not fit in a long but fits in an
unsigned long if long is 32-bit, so it is treated as unsigned long.

The idea is that preprocessor arithmetic is done in the largest standard
integer type available. So C89 compilers use long or unsigned long,
while C99 compilers use intmax_t or uintmax_t (which is at least as wide
as long long).

C89 compilers which support long long as an extension (except I'm not
sure that's strictly speaking a C89 compiler) can complicate this -
obviously "long long" constants should not be truncated to "long".
The most natural solution would be the usual arithmetic conversions -
e.g. ULONG_MAX + 1 == 0L but ULONG_MAX + 1LL promotes ULONG_MAX to
long long so the result is 0x100000000LL or whatever.
 
B

Ben Bacarisse

Ioannis Vranos said:
Ben said:
No, it is talking about two things:

(1) the replacement of defined(WHATEVER) by 1
(2) any other constants that might be there.

When WHATEVER appears *on its own* in an #if expression it will be
replaced by 123 and *that* constant will be considered to be long, but
the text you quote is talking about defined(WHATEVER). The whole
defined(WHATEVER) is replaced by 1 and it is that 1 that is considered
to be long, not int.

In this example:

#if defined(WHATEVER) + defined(NOT_DEFINED_ANYWHERE) + 32 + WHATEVER

there are three substitutions:

defined(WHATEVER) => 1
defined(NOT_DEFINED_ANYWHERE) => 0
WHATEVER => 123

and one "other constant" 32. All of these are to be considered as
having long or unsigned long type.


In the #define SOMETHING 123 case, 123 is considered int or long where
it substitutes SOMETHING, like in

int array[SOMETHING]; ?

No. All of this discussion has been only about how expressions behave
in the pre-processor. Once SOMETHING is replaced by the token 123 in
normal code, it's meaning is defined by the rest of the C standard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top