473,396 Members | 1,929 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

#if sizeof...

Is sizeof() legal within a #if preprocessor line?

Specifically, I would like to use the following "sanity check" at compile
time, but I'm getting an error on the compile about the #if line.

struct foo {
int a;
int b;
};

#if sizeof(struct foo) != 8
#pragma error "sizeof foo is not 8!"
#endif

(Assuming the "#pragma error" generates a compile-time error.)

Yes, I know all about the dangers and non-portability of things like this,
but it's in a low-level TCP/IP communications module, and I'd just like to
add a sanity check at compile time that I'm not on a platform where the
structs don't match the communications protocol.
--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 14 '05 #1
18 21616
On Fri, 14 Jan 2005 12:57:56 -0500, Kenneth Brody wrote:
Is sizeof() legal within a #if preprocessor line?
No.
Specifically, I would like to use the following "sanity check" at compile
time, but I'm getting an error on the compile about the #if line.

struct foo {
int a;
int b;
};

#if sizeof(struct foo) != 8
Another problem would be that struct foo doesn't exist during
preprocessing phases.
#pragma error "sizeof foo is not 8!"
#endif

(Assuming the "#pragma error" generates a compile-time error.)

Yes, I know all about the dangers and non-portability of things like
this, but it's in a low-level TCP/IP communications module, and I'd just
like to add a sanity check at compile time that I'm not on a platform
where the structs don't match the communications protocol.


If you're expecting representation to match there are more issues than
just size.

Lawrence

Nov 14 '05 #2
In article <41***************@spamcop.net>,
Kenneth Brody <ke******@spamcop.net> wrote:
Is sizeof() legal within a #if preprocessor line?
No. The preprocessor doesn't know about such things.
I'd just like to
add a sanity check at compile time that I'm not on a platform where the
structs don't match the communications protocol.


There are various constructs that you could use to produce
compile-time errors if the size is wrong. For example:

char zzz[1 - 2*(sizeof(struct foo) != 8)];

But the error message will not be very enlightening.

-- Richard
Nov 14 '05 #3
Richard Tobin <ri*****@cogsci.ed.ac.uk> wrote:
char zzz[1 - 2*(sizeof(struct foo) != 8)];
A very cute idea! I've stolen it, thank you!

#define CCASSERT(predicate) _x_CCASSERT_LINE(predicate, __LINE__)
[...]
#define _x_CCASSERT_LINE_CAT(predicate, line) \
typedef char constraint_violated_on_line_##line[2*((predicate)!=0)-1];

Due to typedef declaration no object is created, and the declaration
requires `predicate' to be a constant (scalar) expression. Another
equivalent possibility would be to replace "typedef" with "extern".
But the error message will not be very enlightening.


The message from gcc is enough informative:
constr.c:30: size of array `constraint_violated_on_line_30' is negative

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #4
"S.Tobias" wrote:

Richard Tobin <ri*****@cogsci.ed.ac.uk> wrote:
char zzz[1 - 2*(sizeof(struct foo) != 8)];
A very cute idea! I've stolen it, thank you!


ITYM "snarf". ;-)
#define CCASSERT(predicate) _x_CCASSERT_LINE(predicate, __LINE__)
[...]
#define _x_CCASSERT_LINE_CAT(predicate, line) \
typedef char constraint_violated_on_line_##line[2*((predicate)!=0)-1];

Due to typedef declaration no object is created, and the declaration
requires `predicate' to be a constant (scalar) expression. Another
equivalent possibility would be to replace "typedef" with "extern".
But the error message will not be very enlightening.


The message from gcc is enough informative:
constr.c:30: size of array `constraint_violated_on_line_30' is negative


Nice enhancement.

However, why did you switch "1 - 2*x" to "2*x - 1"?

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 14 '05 #5
Lawrence Kirby wrote:

On Fri, 14 Jan 2005 12:57:56 -0500, Kenneth Brody wrote:
Is sizeof() legal within a #if preprocessor line?


No.


That's the conclusion I was coming to. Thanks.

[...]
Yes, I know all about the dangers and non-portability of things like
this, but it's in a low-level TCP/IP communications module, and I'd just
like to add a sanity check at compile time that I'm not on a platform
where the structs don't match the communications protocol.


If you're expecting representation to match there are more issues than
just size.


True. But, as I said, this was just a "sanity check", and "the odds
are" that if the size of the struct matches, the component pieces of
the struct align as expected. Obviously, further testing on a new
platform would be necessary to assure that this was the case.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Nov 14 '05 #6


Kenneth Brody wrote:
Is sizeof() legal within a #if preprocessor line?

Specifically, I would like to use the following "sanity check" at compile
time, but I'm getting an error on the compile about the #if line.

struct foo {
int a;
int b;
};

#if sizeof(struct foo) != 8
#pragma error "sizeof foo is not 8!"
#endif

(Assuming the "#pragma error" generates a compile-time error.)

Yes, I know all about the dangers and non-portability of things like this,
but it's in a low-level TCP/IP communications module, and I'd just like to
add a sanity check at compile time that I'm not on a platform where the
structs don't match the communications protocol.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>


limits.h has the size of all the variables. You should be able to use something
in there to get the size of int.
Nov 14 '05 #7
Neil Kurzman <ns*@mail.asb.com> writes:
Kenneth Brody wrote:
Is sizeof() legal within a #if preprocessor line?

Specifically, I would like to use the following "sanity check" at compile
time, but I'm getting an error on the compile about the #if line.

struct foo {
int a;
int b;
};

#if sizeof(struct foo) != 8
#pragma error "sizeof foo is not 8!"
#endif

(Assuming the "#pragma error" generates a compile-time error.)
[...]
limits.h has the size of all the variables. You should be able to
use something in there to get the size of int.


<limits.h> has the bounds of the predefined integer types, not their
sizes. If there are padding bits, you can't reliably determine their
sizes from their bounds.

Also, that doesn't necessarily give you sizeof(struct foo). The
compiler could insert padding between a and b or after b. That's not
likely for a struct with just two int members (sizeof(struct foo) is
almost certainly equal to 2*sizeof(int)), but presumably the OP wants
to do this for more elaborate types.

Note that you can use assert() to force a run-time error. If the
program aborts immediately, that's almost as good as bombing at
compile time.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #8
Kenneth Brody <ke******@spamcop.net> writes:
[...]
#if sizeof(struct foo) != 8
#pragma error "sizeof foo is not 8!"
#endif

(Assuming the "#pragma error" generates a compile-time error.)


Just use "#error" rather than "#pragma error".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #9
Kenneth Brody wrote on 14/01/05 :
Is sizeof() legal within a #if preprocessor line?


Not portably. A question of stage of translation. At this stage
(preprocessor), the standard says that sizeof is not yet evaluated and
returns 0.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++

Nov 14 '05 #10
Kenneth Brody <ke******@spamcop.net> wrote:
"S.Tobias" wrote:
Richard Tobin <ri*****@cogsci.ed.ac.uk> wrote:
char zzz[1 - 2*(sizeof(struct foo) != 8)];
#define CCASSERT(predicate) _x_CCASSERT_LINE(predicate, __LINE__)
[...]
#define _x_CCASSERT_LINE_CAT(predicate, line) \
typedef char constraint_violated_on_line_##line[2*((predicate)!=0)-1];
Nice enhancement.
....wasn't original either. :-P
I had the idea when I remembered constraints classes in C++ (see Bjarne
Stroustrup's homepage; www.boost.org has a whole library of them).
However, why did you switch "1 - 2*x" to "2*x - 1"?


For no reason; I dont mind 1-2*((predicate)==0), I just want CCASSERT
to fail when `predicate' is false (ie. evaluates to zero or null pointer).

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #11
On 2005-01-14 21:33, Kenneth Brody wrote:
Lawrence Kirby wrote:
On Fri, 14 Jan 2005 12:57:56 -0500, Kenneth Brody wrote:
Is sizeof() legal within a #if preprocessor line? [...] Yes, I know all about the dangers and non-portability of things like
this, but it's in a low-level TCP/IP communications module, and I'd
just like to add a sanity check at compile time that I'm not on a
platform where the structs don't match the communications protocol.


If you're expecting representation to match there are more issues
than just size.


True. But, as I said, this was just a "sanity check", and "the odds
are" that if the size of the struct matches, the component pieces of
the struct align as expected.


That depends on what is 'expected'.

The alignment of fields and the total size of the struct may depend on
their order. On a platform with sizeof(short) = 2 && sizeof(int) == 4
&& sizeof(long) == 8 *and* unaligned access is prohibited by the
underlying hardware, the foo and bar structs shown below will have
different sizes if the compiler pads the struct members:

struct foo { struct bar {
short a; short a;
short b; int c;
int c; short b;
long d; long d;
}; };

Nov 14 '05 #12
S.Tobias wrote:
Richard Tobin <ri*****@cogsci.ed.ac.uk> wrote:
char zzz[1 - 2*(sizeof(struct foo) != 8)];
A very cute idea! I've stolen it, thank you!

#define CCASSERT(predicate) _x_CCASSERT_LINE(predicate, __LINE__)
[...]
#define _x_CCASSERT_LINE_CAT(predicate, line) \
typedef char

constraint_violated_on_line_##line[2*((predicate)!=0)-1];
Due to typedef declaration no object is created, and the declaration
requires `predicate' to be a constant (scalar) expression. Another
equivalent possibility would be to replace "typedef" with "extern".
But the error message will not be very enlightening.
The message from gcc is enough informative:
constr.c:30: size of array `constraint_violated_on_line_30' is

negative
--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`


'extern' is surely better than 'typedef' as the latter has the slight
but neck-breaking chance to end up on the same line in two different
header files or a header file is included twice, which stops
compilation with a illegal redefinition (or worse, silently switches
the compile run to C++). OTOH, I bet someone is working on an
implementation where the linker chokes on the missing definitions for
those externs.

Mark

Nov 14 '05 #13

sorryonly4s...@yahoo.com wrote:
S.Tobias wrote:
Richard Tobin <ri*****@cogsci.ed.ac.uk> wrote:
char zzz[1 - 2*(sizeof(struct foo) != 8)];
A very cute idea! I've stolen it, thank you!

#define CCASSERT(predicate) _x_CCASSERT_LINE(predicate, __LINE__)
[...]
#define _x_CCASSERT_LINE_CAT(predicate, line) \
typedef char

constraint_violated_on_line_##line[2*((predicate)!=0)-1];

Due to typedef declaration no object is created, and the declaration requires `predicate' to be a constant (scalar) expression. Another
equivalent possibility would be to replace "typedef" with "extern".
But the error message will not be very enlightening.


The message from gcc is enough informative:
constr.c:30: size of array `constraint_violated_on_line_30' is

negative

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed

s/[[:upper:]]//g`
'extern' is surely better than 'typedef' as the latter has the slight
but neck-breaking chance to end up on the same line in two different
header files or a header file is included twice, which stops
compilation with a illegal redefinition (or worse, silently switches
the compile run to C++). OTOH, I bet someone is working on an
implementation where the linker chokes on the missing definitions for
those externs.

Mark


Hmmm...I checked and only gcc refuses the compilation of two identical
typedefs, Metrowerks and Borland don't have a problem with them. I
wonder who violates the standard?

Mark

Nov 14 '05 #14
so************@yahoo.com wrote:
Hmmm...I checked and only gcc refuses the compilation of two identical typedefs, Metrowerks and Borland don't have a problem with them. I
wonder who violates the standard?


I don't know but it's really annoying. glibc defines
"typedef unsigned long ulong" depending on what other
switches you have #defined before including a system
header. Some other libraries define the same thing. I
define it in my own code too, for portability. I always
end up with a screenful of defines to ensure ulong is
defined once and only once. (Same goes for ushort, etc.)
I don't see what the problem is with having two identical
typedefs. (Same goes for a re-definition of a macro
to exactly the same thing as it was already defined to).

Nov 14 '05 #15
"Old Wolf" <ol*****@inspire.net.nz> writes:
I don't know but it's really annoying. glibc defines
"typedef unsigned long ulong" depending on what other
switches you have #defined before including a system
header. Some other libraries define the same thing. I
define it in my own code too, for portability.


For portability? You mean, just in case your C compiler doesn't
support "unsigned long" directly?
--
Ben Pfaff
email: bl*@cs.stanford.edu
web: http://benpfaff.org
Nov 14 '05 #16
Kenneth Brody <ke******@spamcop.net> writes:
Is sizeof() legal within a #if preprocessor line?


No.

The definitive (and hilarious) statement on this was posted to
comp.std.c in 1998:

] > You are right. It was nice back in the days when things like
] >
] > #if (sizeof(int) == 8)
] >
] > actually worked (on some compilers).
]
] Must have been before my time.
]
] Dennis

Yes, that was Dennis Ritchie, inventor of C.

<http://groups-beta.google.com/group/comp.std.c/msg/4852afc61a060d89?dmode=source>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #17
On Mon, 17 Jan 2005 12:35:22 -0800, Old Wolf wrote:
so************@yahoo.com wrote:
Hmmm...I checked and only gcc refuses the compilation of two

identical
typedefs, Metrowerks and Borland don't have a problem with them. I
wonder who violates the standard?


The C99 6.7p3 (constraints) says:

"If an identifier has no linkage, there shall be no more than one
declaration of the identifier (in a declarator or type specifier) with
the same scope and in the same name space, except for tags as specified
in 6.7.2.3."

So 2 identical typedefs at, say, file scope require a diagnostic. Maybe
Metrowerks and Borland need an option to make them conforming in this
respect.

Lawrence

Nov 14 '05 #18
Keith Thompson wrote:

Kenneth Brody <ke******@spamcop.net> writes:
Is sizeof() legal within a #if preprocessor line?


No.

The definitive (and hilarious) statement on this was posted to
comp.std.c in 1998:

] > You are right. It was nice back in the days when things like
] >
] > #if (sizeof(int) == 8)
] >
] > actually worked (on some compilers).
]
] Must have been before my time.
]
] Dennis

Yes, that was Dennis Ritchie, inventor of C.

<http://groups-beta.google.com/group/comp.std.c/msg/4852afc61a060d89?dmode=source>


Thanks for the chuckle.

Reminds me of the story regarding a conference where a speaker got into a
discussion regarding compatibility with the Korn shell, and it turned out
that the audience member he was arguing with was David Korn himself. (I
couldn't remember enough of the story to Google it.)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Nov 14 '05 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Sunil Menon | last post by:
Dear All, A class having no member variables and only a method sizeof(object) will return 1byte in ANSI and two bytes in Unicode. I have the answer for this of how in works in ANSI. But I don't...
2
by: Xiangliang Meng | last post by:
Hi, all. What will we get from sizeof(a class without data members and virtual functions)? For example: class abnormity { public: string name() { return "abnormity"; }
19
by: Martin Pohlack | last post by:
Hi, I have a funtion which shall compute the amount for a later malloc. In this function I need the sizes of some struct members without having an instance or pointer of the struct. As...
9
by: M Welinder | last post by:
This doesn't work with any C compiler that I can find. They all report a syntax error: printf ("%d\n", (int)sizeof (char)(char)2); Now the question is "why?" "sizeof" and "(char)" have...
7
by: dam_fool_2003 | last post by:
#include<stdio.h> int main(void) { unsigned int a=20,b=50, c = sizeof b+a; printf("%d\n",c); return 0; } out put: 24
42
by: Christopher C. Stacy | last post by:
Some people say sizeof(type) and other say sizeof(variable). Why?
8
by: junky_fellow | last post by:
Consider the following piece of code: #include <stddef.h> int main (void) { int i, j=1; char c; printf("\nsize =%lu\n", sizeof(i+j));
90
by: pnreddy1976 | last post by:
Hi, How can we write a function, which functionality is similar to sizeof function any one send me source code Reddy
32
by: Abhishek Srivastava | last post by:
Hi, Somebody recently asked me to implement the sizeof operator, i.e. to write a function that accepts a parameter of any type, and without using the sizeof operator, should be able to return...
5
by: Francois Grieu | last post by:
Does this reliably cause a compile-time error when int is not 4 bytes ? enum { int_size_checked = 1/(sizeof(int)==4) }; Any better way to check the value of an expression involving sizeof...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.