468,512 Members | 1,369 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,512 developers. It's quick & easy.

#if constant expression

According to 6.8 of C90, #if takes a constant expression.

According to 6.4 of C90, the sizeof operator is part of a constant
expression.

Why then do most of my compilers barf on this?

#include <stdio.h>

#if sizeof(int) >= 4
#define XXX "big"
#else
#define XXX "small"
#endif

int main(void)
{
printf("hello %s\n", XXX);
return (0);
}

They barf on the "#if sizeof ..." line.

They explicitly say that I can't use sizeof in a #if

So which bit of the standard did I miss?

BFN. Paul.
Dec 10 '07 #1
11 3780
#include <stdio.h>
>
#if sizeof(int) >= 4
#define XXX "big"
#else
#define XXX "small"
#endif

int main(void)
{
printf("hello %s\n", XXX);
return (0);

}
[code snnipet...]
So which bit of the standard did I miss?

Well I think that #if can be used only with the Macros(who gets
replaced with contant expressions at compile time) since sizeof gets
resolved at run time I dont think it's good idea to use sizeof with
#if!!

Regards
Vikas Gupta
Dec 10 '07 #2
kerravon wrote:
According to 6.8 of C90, #if takes a constant expression.

According to 6.4 of C90, the sizeof operator is part of a constant
expression.

Why then do most of my compilers barf on this?

#include <stdio.h>

#if sizeof(int) >= 4
#define XXX "big"
#else
#define XXX "small"
#endif

int main(void)
{
printf("hello %s\n", XXX);
return (0);
}

They barf on the "#if sizeof ..." line.

They explicitly say that I can't use sizeof in a #if

So which bit of the standard did I miss?

BFN. Paul.
I don't have a copy of C90; but I suspect that this is not an area where
the differences between C90 and C99 matter. Section 6.10.1p4 of
n1256.pdf says

"After all replacements due to macro expansion and the *defined* unary
operator have been performed, all remaining identifiers (including those
lexically identical to keywords) are replaced with the pp-number 0, "

I believe that this applies to both 'sizeof' and 'int' in your example.
As a result, it becomes:

#if 0(0) >= 4

which explains why it fails.
Dec 10 '07 #3
vicks <vi*******@gmail.comwrote in news:d485a4a6-dd4a-492e-a00b-
9b**********@r1g2000hsg.googlegroups.com:
Well I think that #if can be used only with the Macros(who gets
replaced with contant expressions at compile time) since sizeof gets
resolved at run time I dont think it's good idea to use sizeof with
#if!!

sizeof yields a compile-time constant, and is very much _not_ evaluated at
runtime.

--
Tomás Ó hÉilidhe
Dec 10 '07 #4
kerravon wrote:
>
According to 6.8 of C90, #if takes a constant expression.

According to 6.4 of C90, the sizeof operator is part of a constant
expression.
The preprocessor can't read keywords.
ISO/IEC 9899: 1990
6.8.1 Conditional inclusion
Constraints

identifiers (including those lexically identical to keywords)
are interpreted as described below;83

83 Because the controlling constant expression
is evaluated during translation phase 4,
all identifiers either are or are not macro names
— there simply are no keywords, enumeration constants, etc.
--
pete
Dec 10 '07 #5
On Dec 10, 8:11 am, pete <pfil...@mindspring.comwrote:
kerravon wrote:
According to 6.8 of C90, #if takes a constant expression.
According to 6.4 of C90, the sizeof operator is part of a constant
expression.

The preprocessor can't read keywords.

ISO/IEC 9899: 1990
6.8.1 Conditional inclusion
Constraints

identifiers (including those lexically identical to keywords)
are interpreted as described below;83

83 Because the controlling constant expression
is evaluated during translation phase 4,
all identifiers either are or are not macro names
-- there simply are no keywords, enumeration constants, etc.

--
pete
#if is for preprocessor, sizeof is a compile time operator but not
handled at preprocessing stage. If you have gcc put sizeof in your
code and run gcc -E <soure filenameit should give you the
preprocessor output and sizeof would remain as it is.
Dec 10 '07 #6
In article
<81**********************************@d21g2000prf. googlegroups.com>,
kerravon <ke******@w3.towrote:
Why then do most of my compilers barf on this?
#include <stdio.h>
#if sizeof(int) >= 4
#define XXX "big"
#else
#define XXX "small"
#endif
int main(void)
{
printf("hello %s\n", XXX);
return (0);
}

One way to see this is that sizeof is not usable in the proprocessor, which has no
knowledge of types. There is a solution, though

#include <stdio.h>
#define XXX (sizeof(int) >= 4 ? "big" : "small")
int main(void)
{
printf("hello %s\n", XXX);
return (0);
}

If you want to check at compile time that int is big:
/* cause a compile-time error if x is 0 */
#define CompileAssert(x) do{typedef struct{char f[(x)?1:-1];}assertion_failure;}while(0) /* compile time assertion failure */

#include <stdio.h>
int main(void)
{
CompileAssert(sizeof(int) >= 4);
puts("hello big");
return (0);
}
Francois Grieu
Dec 10 '07 #7
Keith Thompson wrote:
>
pete <pf*****@mindspring.comwrites:
ISO/IEC 9899: 1990
6.8.1 Conditional inclusion
Constraints

identifiers (including those lexically identical to keywords)
are interpreted as described below;83

83 Because the controlling constant expression
is evaluated during translation phase 4,
all identifiers either are or are not macro names
-- there simply are no keywords, enumeration constants, etc.

That quotation is from the C99 standard, not the C90 standard.
That quotation is from the C90 standard.
I think you must be using a public draft instead.
This quotation is from the C99 standard:

ISO/IEC 9899:1999(E)
6.10.1 Conditional inclusion
Constraints

identifiers (including those lexically identical to keywords)
are interpreted as described below;140)

140) Because the controlling constant expression
is evaluated during translation phase 4,
all identifiers either are or are not macro names
— there simply are no keywords, enumeration constants, etc.

--
pete
Dec 10 '07 #8
pete <pf*****@mindspring.comwrites:
Keith Thompson wrote:
>pete <pf*****@mindspring.comwrites:
ISO/IEC 9899: 1990
6.8.1 Conditional inclusion
Constraints

identifiers (including those lexically identical to keywords)
are interpreted as described below;83

83 Because the controlling constant expression
is evaluated during translation phase 4,
all identifiers either are or are not macro names
-- there simply are no keywords, enumeration constants, etc.

That quotation is from the C99 standard, not the C90 standard.

That quotation is from the C90 standard.
I think you must be using a public draft instead.
No, I'm using a copy of the actual C90 standard, but you're right, the
quotation is from the C90 standard. I don't know how I missed that.
Apologies.

[...]

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 11 '07 #9
pete <pf*****@mindspring.comwrites:
Keith Thompson wrote:
>>
pete <pf*****@mindspring.comwrites:
ISO/IEC 9899: 1990
6.8.1 Conditional inclusion
Constraints

identifiers (including those lexically identical to keywords)
are interpreted as described below;83

83 Because the controlling constant expression
is evaluated during translation phase 4,
all identifiers either are or are not macro names
-- there simply are no keywords, enumeration constants, etc.

That quotation is from the C99 standard, not the C90 standard.

That quotation is from the C90 standard.
I think you must be using a public draft instead.
No, I'm using a copy of the actual C90 standard, but you're right, the
quotation is from the C90 standard. I don't know how I missed that.
Apologies.

[...]

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 11 '07 #10
kerravon <ke******@w3.towrote:
# According to 6.8 of C90, #if takes a constant expression.
#
# According to 6.4 of C90, the sizeof operator is part of a constant
# expression.

You conceptual have the stages
(1) preprocessor
(2) parser
(3) code generator

sizeof is a constant in third stage (code generator) which
comes after the preprocessor. You should not expect this kind
of backwards information flow from code generator to the
preprocessor.

One work around is write a small program that does the sizeof
and then writes an include file with appropriate defines.

# #if sizeof(int) >= 4
# #define XXX "big"
# #else
# #define XXX "small"
# #endif

For example, with make you can have something like

defineXXX.c :
#include <stdio.h>
int main(int N,char **P) {
if (sizeof(int)>=4)) puts("#define XXX \"big\"");
else puts("#define XXX \"small\"");
return 0;
}

main.c:
#include <stdio.h>
#include "XXX.h"

int main(void)
{
printf("hello %s\n", XXX);
return (0);
}

makefile:
main: main.c XXX.h
cc -o main main.c
XXX.h: defineXXX
defineXXX XXX.h
defineXXX: defineXXX.c
cc -o defineXXX defineXXX.c

--
SM Ryan http://www.rawbw.com/~wyrmwif/
This is one wacky game show.
Dec 11 '07 #11
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrites:
kerravon <ke******@w3.towrote:
According to 6.8 of C90, #if takes a constant expression.

According to 6.4 of C90, the sizeof operator is part of a constant
expression.

You conceptual have the stages
(1) preprocessor
(2) parser
(3) code generator

sizeof is a constant in third stage (code generator) which
comes after the preprocessor. You should not expect this kind
of backwards information flow from code generator to the
preprocessor.

One work around is write a small program that does the sizeof
and then writes an include file with appropriate defines.
#if sizeof(int) >= 4
#define XXX "big"
#else
#define XXX "small"
#endif

For example, with make you can have something like

defineXXX.c :
#include <stdio.h>
int main(int N,char **P) {
if (sizeof(int)>=4)) puts("#define XXX \"big\"");
else puts("#define XXX \"small\"");
return 0;
}

main.c:
#include <stdio.h>
#include "XXX.h"

int main(void)
{
printf("hello %s\n", XXX);
return (0);
}

makefile:
main: main.c XXX.h
cc -o main main.c
XXX.h: defineXXX
defineXXX XXX.h
defineXXX: defineXXX.c
cc -o defineXXX defineXXX.c
Taking the system-specific makefile syntax as an *example* of the
general approach, I'll point out that this works only when the
software is being compiled on the same system that it's being compiled
for. For cross-compilation, you'd need to arrange for the "defineXXX"
program to be executed on the target, and the output copied back to
the host system.

<OT>And you'd want "./defineXXX", not "defineXXX".</OT>

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 11 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

15 posts views Thread by Chris Saunders | last post: by
13 posts views Thread by devdatta_clc | last post: by
1 post views Thread by Andrzej 'Foxy' D. | last post: by
3 posts views Thread by lovecreatesbeauty | last post: by
3 posts views Thread by Dan Smithers | last post: by
7 posts views Thread by John Koleszar | last post: by
7 posts views Thread by Hendrik Schober | last post: by
8 posts views Thread by Stefano Sabatini | last post: by
8 posts views Thread by PJ6 | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by fmendoza | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.