470,833 Members | 1,379 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

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

Pre-processor peculiarities

I have an issue which I don't seem to be able to solve, and which has
haunted me from time to time for years. Solution to either of the
points below would help me immensely (the compiler I have is a plain C-
compiler without C++):

* Is there any way to determine is a 'typedef' is defined during
compile time without depending on if a corresponding HAS_xxx_t (or
something similar) has been defined with #define?

* Is there any way to #define something inside a macro? For example,
the following works:

#define DEF_STRUCT( NAME, STRUCTURE ) \
typedef struct{ \
STRUCTURE \
}frame_##NAME##_t;

From within the code I can then define the structure like this:

DEF_STRUCT( MY_FRAME,
int32_t foo:24;
int32_t bar:24;
);

However if I add an extra line last in the macro defining if the
structure is existent or not, the compiler complains:

#define DEF_STRUCT( NAME, STRUCTURE ) \
typedef struct{ \
STRUCTURE \
}frame_##NAME##_t; \
#define HAS_##NAME
* Is there any way of defining something that when combined with the
sizeof operator would result in 0?

Defining an empty structure apparently isn't legal and can't be used
as a type resulting in a zero size.
Many thanks
/Michael
Jun 27 '08 #1
3 1091
Mamluk Caliph wrote:
I have an issue which I don't seem to be able to solve, and which has
haunted me from time to time for years. Solution to either of the
points below would help me immensely (the compiler I have is a plain C-
compiler without C++):

* Is there any way to determine is a 'typedef' is defined during
compile time without depending on if a corresponding HAS_xxx_t (or
something similar) has been defined with #define?
No. The preprocessor makes its decisions before the
compiler recognizes and processes type declarations. When
the preprocessor operates, even things like `int' and `for'
do not yet have any special significance.
* Is there any way to #define something inside a macro? For example,
the following works:

#define DEF_STRUCT( NAME, STRUCTURE ) \
typedef struct{ \
STRUCTURE \
}frame_##NAME##_t;

From within the code I can then define the structure like this:

DEF_STRUCT( MY_FRAME,
int32_t foo:24;
int32_t bar:24;
);
Ugh. "Beauty is in the eye of the beholder," but Ugh
nonetheless. Also, you'll get into trouble if anybody ever
tries something like

DEF_STRUCT( MY_FRAME,
int a, b, c;
};
However if I add an extra line last in the macro defining if the
structure is existent or not, the compiler complains:

#define DEF_STRUCT( NAME, STRUCTURE ) \
typedef struct{ \
STRUCTURE \
}frame_##NAME##_t; \
#define HAS_##NAME
This will not work and cannot be made to work. Even if a
macro expands to something that looks like a preprocessor
directive, the expansion is not processed as a directive.
* Is there any way of defining something that when combined with the
sizeof operator would result in 0?

Defining an empty structure apparently isn't legal and can't be used
as a type resulting in a zero size.
If by "combined with" you mean "used as the operand of,"
the answer is No. Every C type either has a size of at least
one byte, or has no size at all (which is not the same thing
as having a size of zero bytes).

What problem are you trying to solve by using a zero-sized
type?

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #2
This will not work and cannot be made to work. Even if a
macro expands to something that looks like a preprocessor
directive, the expansion is not processed as a directive.
Would this them mean that no processor directive is ever legal inside
a macro (i.e. anything with a number sign not meant for
stringification of concatenation)?

If by "combined with" you mean "used as the operand of,"
the answer is No. Every C type either has a size of at least
one byte, or has no size at all (which is not the same thing
as having a size of zero bytes).
Yes, as in "used as the operand of". How can you define something as
having no size? I'm thinking of something like the following perhaps
could be used to solve my problem:

if (sizeof(nosize_t) == 0)
fo();
>
What problem are you trying to solve by using a zero-sized
type?

I'm trying to re-use a macro looking like this:

#define MSG_INIT( VAR , CMD) \
DEF_MSG_SIMPLE( VAR ,HEADERID_##CMD, sizeof(frame_##CMD##_t) )

This is used for initializing a message header in a field-bus based
system with many hundred unique ID.s. The problem is that sometimes
messages have no data (i.e. there exists no frame_XXX_t). The macro
could be expanded to take the size as an argument as well, but then if
the data format changes, one would have to search and replace in
application code.

Defining anything that could be usable inside the macro, but that at
the same time wouldn't imply changes to the application code would
work. I.e. I was thinking of defining "dummy" types for those messages
missing data returning the size zero, but I can't figure out how.

Regards
/Michael



Jun 27 '08 #3
Mamluk Caliph wrote:
> This will not work and cannot be made to work. Even if a
macro expands to something that looks like a preprocessor
directive, the expansion is not processed as a directive.

Would this them mean that no processor directive is ever legal inside
a macro (i.e. anything with a number sign not meant for
stringification of concatenation)?
It means the macro expansion is never a preprocessor
directive, not even if it looks like one. Off-hand, I cannot
think of a context where a directive-like expansion would
not be an error.
> If by "combined with" you mean "used as the operand of,"
the answer is No. Every C type either has a size of at least
one byte, or has no size at all (which is not the same thing
as having a size of zero bytes).

Yes, as in "used as the operand of". How can you define something as
having no size?
Incomplete types, bit-fields, and functions have no size:

struct undefined *p;
void *q;
struct { int b : 4; } s;
int (*f)(double);

n = sizeof *p; /* BZZZT! */
n = sizeof *q; /* BZZZT! */
n = sizeof s.b; /* BZZZT! */
n = sizeof *f; /* BZZZT! */
> What problem are you trying to solve by using a zero-sized
type?

I'm trying to re-use a macro looking like this:

#define MSG_INIT( VAR , CMD) \
DEF_MSG_SIMPLE( VAR ,HEADERID_##CMD, sizeof(frame_##CMD##_t) )

This is used for initializing a message header in a field-bus based
system with many hundred unique ID.s. The problem is that sometimes
messages have no data (i.e. there exists no frame_XXX_t). The macro
could be expanded to take the size as an argument as well, but then if
the data format changes, one would have to search and replace in
application code.

Defining anything that could be usable inside the macro, but that at
the same time wouldn't imply changes to the application code would
work. I.e. I was thinking of defining "dummy" types for those messages
missing data returning the size zero, but I can't figure out how.
It sounds to me like you're trying to use zero-sized types
as a hack to compensate for the deficiencies of the macro.
Maybe it would be better to improve the macro than to attempt
the hack, possibly by introducing another macro for the no-data
case. (Presumably it is known which messages have no data, or
you wouldn't know which fake types to define.)

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

21 posts views Thread by Headless | last post: by
7 posts views Thread by Alan Illeman | last post: by
2 posts views Thread by Buck Turgidson | last post: by
5 posts views Thread by Michael Shell | last post: by
8 posts views Thread by Jarno Suni not | last post: by
9 posts views Thread by Eric Lindsay | last post: by
14 posts views Thread by Schraalhans Keukenmeester | last post: by
reply views Thread by mihailmihai484 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.