473,408 Members | 1,623 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,408 software developers and data experts.

Macro redefinition

I'm implementing a parser, where there is a lot of different data
elements defined. Now instead of hand-coding X defines, and the massive
number of lines needed for table initialization, I decided to generate
this source instead.
So, I basically used this trick:

void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"

}

where the "iso8583_defs" file, did contain a lot of lines like this:

EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);
My question is simply, is the above C code allowed?
--
Tor <torust [at] online [dot] no>
Aug 31 '07 #1
19 8394
Tor Rustad <to********@hotmail.comwrites:
void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"

}

where the "iso8583_defs" file, did contain a lot of lines like this:

EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);
My question is simply, is the above C code allowed?
Sure. Lots of code uses this trick to avoid redundancy.

If you don't like the idea of using an include file for this, you
can also use a macro:

void gen_source_function(FILE *out)
{
#define ISO8583_DEFS \
EXPAND_DEF(1, FIELD_NAME); \
EXPAND_DEF(2, ANOTHER_FIELD_NAME);

#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
ISO8583_DEFS

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
ISO8583_DEFS
}

I think it's a toss-up which is better. Neither is pretty, both
are functional.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
Aug 31 '07 #2
On Aug 31, 11:04 am, Tor Rustad <tor_rus...@hotmail.comwrote:
I'm implementing a parser, where there is a lot of different data
elements defined. Now instead of hand-coding X defines, and the massive
number of lines needed for table initialization, I decided to generate
this source instead.

So, I basically used this trick:

void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"

}

where the "iso8583_defs" file, did contain a lot of lines like this:

EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);

My question is simply, is the above C code allowed?
It's a pretty common idiom in the code I work with. One caveat: don't
forget to #undef EXPAND_DEF before redefining it.

Regards,

-=Dave

Aug 31 '07 #3
Ben Pfaff wrote:
Tor Rustad <to********@hotmail.comwrites:
>void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"

}

where the "iso8583_defs" file, did contain a lot of lines like this:

EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);
My question is simply, is the above C code allowed?

Sure. Lots of code uses this trick to avoid redundancy.
Yup, that's the idea.
If you don't like the idea of using an include file for this, you
can also use a macro:

void gen_source_function(FILE *out)
{
#define ISO8583_DEFS \
EXPAND_DEF(1, FIELD_NAME); \
EXPAND_DEF(2, ANOTHER_FIELD_NAME);

#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
ISO8583_DEFS

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
ISO8583_DEFS
}
Interesting, I haven't seen this solution before.

However, there is a translation limit of "509 characters in a logical
source line", and isn't logical source lines made up after line-splicing
your ISO8583_DEFS above?

--
Tor <torust [at] online [dot] no>
Aug 31 '07 #4
Dave Hansen wrote:

<snip>
>My question is simply, is the above C code allowed?

It's a pretty common idiom in the code I work with. One caveat: don't
forget to #undef EXPAND_DEF before redefining it.
Is really the #undef needed in this case? This is a function-like macro,
and the re-definition had identical argument list.

--
Tor <torust [at] online [dot] no>
Aug 31 '07 #5
Tor Rustad <to********@hotmail.comwrites:
Dave Hansen wrote:

<snip>
>>My question is simply, is the above C code allowed?
It's a pretty common idiom in the code I work with. One caveat:
don't
forget to #undef EXPAND_DEF before redefining it.

Is really the #undef needed in this case? This is a function-like
macro, and the re-definition had identical argument list.
C99 6.10.3p2:

An identifier currently defined as an object-like macro shall not
be redefined by another #define preprocessing directive unless the
second definition is an object-like macro definition and the two
replacement lists are identical. Likewise, an identifier currently
defined as a function-like macro shall not be redefined by another
#define preprocessing directive unless the second definition is a
function-like macro definition that has the same number and
spelling of parameters, and the two replacement lists are
identical.

This is a constraint.

--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 31 '07 #6
Tor Rustad <to********@hotmail.comwrites:
However, there is a translation limit of "509 characters in a logical
source line", and isn't logical source lines made up after
line-splicing your ISO8583_DEFS above?
Interesting point. I've not run into an implementation (yet)
that has such a stringent limit. I notice that C99 expanded the
limit to 4095 characters.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Aug 31 '07 #7
Keith Thompson wrote:
Tor Rustad <to********@hotmail.comwrites:
>Dave Hansen wrote:

<snip>
>>>My question is simply, is the above C code allowed?
It's a pretty common idiom in the code I work with. One caveat:
don't
forget to #undef EXPAND_DEF before redefining it.
Is really the #undef needed in this case? This is a function-like
macro, and the re-definition had identical argument list.

C99 6.10.3p2:

An identifier currently defined as an object-like macro shall not
be redefined by another #define preprocessing directive unless the
second definition is an object-like macro definition and the two
replacement lists are identical. Likewise, an identifier currently
defined as a function-like macro shall not be redefined by another
#define preprocessing directive unless the second definition is a
function-like macro definition that has the same number and
spelling of parameters, and the two replacement lists are
identical.

This is a constraint.
Keith, I don't get your point. Doesn't the

"unless the second definition is a function-like macro definition that
has the same number and spelling of parameters, and the two replacement
lists are identical"

apply?

--
Tor <torust [at] online [dot] no>
Aug 31 '07 #8
Ben Pfaff wrote:
Tor Rustad <to********@hotmail.comwrites:
>However, there is a translation limit of "509 characters in a logical
source line", and isn't logical source lines made up after
line-splicing your ISO8583_DEFS above?

Interesting point. I've not run into an implementation (yet)
that has such a stringent limit. I notice that C99 expanded the
limit to 4095 characters.
In my case, there will be _at least_ 128 lines to splice, each line on
average ca. 50 characters long, in total 6400 characters minimum.

--
Tor <torust [at] online [dot] no>
Aug 31 '07 #9
In article <LN*********************@telenor.com>,
Tor Rustad <to********@hotmail.comwrote:
>Keith, I don't get your point. Doesn't the

"unless the second definition is a function-like macro definition that
has the same number and spelling of parameters, and the two replacement
lists are identical"

apply?
The replacement lists were different. One had generate_source_1,
the other generate_source_2. There wouldn't have been much point
if they were the same.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 31 '07 #10
Tor Rustad <to********@hotmail.comwrites:
>Tor Rustad <to********@hotmail.comwrites:
>>Dave Hansen wrote:
My question is simply, is the above C code allowed?
It's a pretty common idiom in the code I work with. One caveat:
don't
forget to #undef EXPAND_DEF before redefining it.
Is really the #undef needed in this case? This is a function-like
macro, and the re-definition had identical argument list.
Doesn't the

"unless the second definition is a function-like macro definition that
has the same number and spelling of parameters, and the two
replacement lists are identical"

apply?
Your replacement lists are different: the first has
generate_source_1, the second has generate_source_2.
--
"It would be a much better example of undefined behavior
if the behavior were undefined."
--Michael Rubenstein
Aug 31 '07 #11
Tor Rustad <to********@hotmail.comwrites:
Ben Pfaff wrote:
>Tor Rustad <to********@hotmail.comwrites:
>>However, there is a translation limit of "509 characters in a logical
source line", and isn't logical source lines made up after
line-splicing your ISO8583_DEFS above?

Interesting point. I've not run into an implementation (yet)
that has such a stringent limit. I notice that C99 expanded the
limit to 4095 characters.

In my case, there will be _at least_ 128 lines to splice, each line on
average ca. 50 characters long, in total 6400 characters minimum.
Then you'd definitely be better off an include file.
--
"I should killfile you where you stand, worthless human." --Kaz
Aug 31 '07 #12
Tor Rustad wrote:
I'm implementing a parser, where there is a lot of different data
elements defined. Now instead of hand-coding X defines, and the massive
number of lines needed for table initialization, I decided to generate
this source instead.
So, I basically used this trick:

void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"

}

where the "iso8583_defs" file, did contain a lot of lines like this:

EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);

My question is simply, is the above C code allowed?
With the require #unded as explained else thread, it is quite common.

One project I worked on used it extensively, but with hind site, we
found the code hard to maintain, so we dropped the technique and used
code generation from XML instead.

--
Ian Collins.
Aug 31 '07 #13
Ben Pfaff wrote:
Tor Rustad <to********@hotmail.comwrites:
>>Tor Rustad <to********@hotmail.comwrites:
Dave Hansen wrote:
>My question is simply, is the above C code allowed?
It's a pretty common idiom in the code I work with. One caveat:
don't
forget to #undef EXPAND_DEF before redefining it.
Is really the #undef needed in this case? This is a function-like
macro, and the re-definition had identical argument list.
Doesn't the

"unless the second definition is a function-like macro definition that
has the same number and spelling of parameters, and the two
replacement lists are identical"

apply?

Your replacement lists are different: the first has
generate_source_1, the second has generate_source_2.
Ahh.. I see and learned something new! :-)

--
Tor <torust [at] online [dot] no>
Aug 31 '07 #14
Ian Collins wrote:
Tor Rustad wrote:
>I'm implementing a parser, where there is a lot of different data
elements defined. Now instead of hand-coding X defines, and the massive
number of lines needed for table initialization, I decided to generate
this source instead.
[...]
One project I worked on used it extensively, but with hind site, we
found the code hard to maintain, so we dropped the technique and used
code generation from XML instead.
For now, I only need to parse messages of the ISO 8583 1993 standard,
one future complication could be to handle the 1987 and 2001 standards
as well. Even so, I can't see how the parser code could become hard to
maintain. The source generator program is tiny, it's input table is "small".

In a more complex case, XML could perhaps give something, but in this
case I would rather write an ASN.1 specification and have the C code
generated by an ASN.1 compiler.
Generally, I'm *sick* of all that XML wasting HD space and network
bandwidth these days... *yuck*
--
Tor <torust [at] online [dot] no>
Sep 1 '07 #15
Ben Pfaff wrote:
Tor Rustad <to********@hotmail.comwrites:
>void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"

}

where the "iso8583_defs" file, did contain a lot of lines like this:

EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);
My question is simply, is the above C code allowed?

Sure. Lots of code uses this trick to avoid redundancy.

If you don't like the idea of using an include file for this, you
can also use a macro:

void gen_source_function(FILE *out)
{
#define ISO8583_DEFS \
EXPAND_DEF(1, FIELD_NAME); \
EXPAND_DEF(2, ANOTHER_FIELD_NAME);

#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
ISO8583_DEFS

#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
ISO8583_DEFS
}

I think it's a toss-up which is better. Neither is pretty, both
are functional.
Here's another way to do it. Include the macro file, as first proposed,
but make it the same as the including file! Here's an example:

//* incex.c - Show example of self inclusion */
#ifdef M1
M1(Sharon)
M1(Robert)
M1(Nancy)
#else

#include <stdio.h>

#define M1(n) n,
enum names {
#include "incex.c" /* include self for M1 list */
N_NAMES
};
#undef M1

#define M1(n) #n,
const char *const namestring[] = {
#include "incex.c" /* include self for M1 list */
""
};
#undef M1

int main (void) {
enum names i;

for (i=Robert; i <= Nancy; i++) {
printf ("%d: %s\n", i, namestring[i]);
}
return 0;
}
#endif
----------------
Pretty sleazy, but it only has a single list and is self contained! You
can even extend it to multiple macro lists.
--
Thad
Sep 1 '07 #16
On Aug 31, 4:06 pm, Ian Collins <ian-n...@hotmail.comwrote:
Tor Rustad wrote:
I'm implementing a parser, where there is a lot of different data
elements defined. Now instead of hand-coding X defines, and the massive
number of lines needed for table initialization, I decided to generate
this source instead.
So, I basically used this trick:
void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"
#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"
}
where the "iso8583_defs" file, did contain a lot of lines like this:
EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);
My question is simply, is the above C code allowed?

With the require #unded as explained else thread, it is quite common.

One project I worked on used it extensively, but with hind site, we
found the code hard to maintain, so we dropped the technique and used
code generation from XML instead.
Yes. I've had a similar experience. "Preprocessor abuse" has often
led me to a place where something that needed to be done was beyond
the cpp to handle. Using python or perl or similar to generate code
is better in the long run. Most recently, I've used TXL (txl.ca) as a
very robust and maintainable way to (among other things) implement a
language extension inside an established language.
Sep 1 '07 #17
Thad Smith wrote:

<snip>

Here's another way to do it. Include the macro file, as first proposed,
but make it the same as the including file! Here's an example:

//* incex.c - Show example of self inclusion */
#ifdef M1
M1(Sharon)
M1(Robert)
M1(Nancy)
#else

#include <stdio.h>

#define M1(n) n,
enum names {
#include "incex.c" /* include self for M1 list */
N_NAMES
};
#undef M1

#define M1(n) #n,
const char *const namestring[] = {
#include "incex.c" /* include self for M1 list */
""
};
#undef M1

int main (void) {
enum names i;

for (i=Robert; i <= Nancy; i++) {
printf ("%d: %s\n", i, namestring[i]);
}
return 0;
}
#endif
----------------
Pretty sleazy, but it only has a single list and is self contained! You
can even extend it to multiple macro lists.
Ahh.. that was a clever solution! One pass, no need for a
generator program.
--
Tor <torust [at] online [dot] no>
Sep 1 '07 #18
"Tor Rustad" <to********@hotmail.comwrote in message
news:LN*********************@telenor.com...
Keith Thompson wrote:
>Tor Rustad <to********@hotmail.comwrites:
>>Dave Hansen wrote:
My question is simply, is the above C code allowed?

It's a pretty common idiom in the code I work with. One caveat:
don't
forget to #undef EXPAND_DEF before redefining it.

Is really the #undef needed in this case? This is a function-like
macro, and the re-definition had identical argument list.

C99 6.10.3p2:

An identifier currently defined as an object-like macro shall not
be redefined by another #define preprocessing directive unless
the second definition is an object-like macro definition and the
two replacement lists are identical. Likewise, an identifier
currently defined as a function-like macro shall not be redefined
by another #define preprocessing directive unless the second
definition is a function-like macro definition that has the same
number and spelling of parameters, and the two replacement
lists are identical.

This is a constraint.

Keith, I don't get your point. Doesn't the

"unless the second definition is a function-like macro definition
that has the same number and spelling of parameters, and the
two replacement lists are identical"

apply?
Benign redefinition only exists when you do the same thing twice. For
instance, this is okay:

#define FOO 1
#define FOO 1

This is not:

#define FOO 1
#define FOO 2

In the latter case, you need to #undef FOO before you redefine it.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
--
Posted via a free Usenet account from http://www.teranews.com

Sep 1 '07 #19
Gene wrote:
On Aug 31, 4:06 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Tor Rustad wrote:
>>I'm implementing a parser, where there is a lot of different data
elements defined. Now instead of hand-coding X defines, and the massive
number of lines needed for table initialization, I decided to generate
this source instead.
So, I basically used this trick:
void gen_source_function(FILE *out)
{
#define EXPAND_DEF(num, name) generate_source_1(out, num, #name)
#include "iso8583_defs"
#define EXPAND_DEF(num, name) generate_source_2(out, num, #name)
#include "iso8583_defs"
}
where the "iso8583_defs" file, did contain a lot of lines like this:
EXPAND_DEF(1, FIELD_NAME);
EXPAND_DEF(2, ANOTHER_FIELD_NAME);
My question is simply, is the above C code allowed?
With the require #unded as explained else thread, it is quite common.

One project I worked on used it extensively, but with hind site, we
found the code hard to maintain, so we dropped the technique and used
code generation from XML instead.

Yes. I've had a similar experience. "Preprocessor abuse" has often
led me to a place where something that needed to be done was beyond
the cpp to handle. Using python or perl or similar to generate code
is better in the long run. Most recently, I've used TXL (txl.ca) as a
very robust and maintainable way to (among other things) implement a
language extension inside an established language.

In this application, perl, python or TXL work as external preproccessor
(a converter of input text to output text while doing changes as
instructed by preprocessor directives (scripts)).
To that end, I'd humbly suggest to take a look at my article "Picking
the right code preprocessor" (e.g.
http://www.wirelessnetdesignline.com...ing/199905675).
--
Ark
Sep 3 '07 #20

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

Similar topics

5
by: lomat | last post by:
Hello, While compiling a file, I get following error .... ================================= /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/include/g++/type_traits.h:14 2: redefinition of...
69
by: Ken | last post by:
Hi all. When referring to a null pointer constant in C++, is there any reason to prefer using 0 over a macro called NULL that is defined to be 0? Thanks! Ken
13
by: Gernot Frisch | last post by:
What does the standart say: for (long i=0; i<0; ++i) ; for (myclass i=0; i<0; ++i); is it allowed? i only is defined in the for-loop space, isn't it? VC6 gives me an *error*, not just a...
1
by: squallions | last post by:
Hi I doing my c++ homework and stuck on error 'class' type redefinition. I have 5 classes. First class is base class. The next two classes are derived from the first class. The next two...
3
by: Colin Kiegel | last post by:
Hi there! My aim is to analyse a couple of code-segments. I want to know how much time is spent at their execution. I successfuly wrapped QueryPerformanceCounter for that purpose. But my...
5
by: Patrick Kowalzick | last post by:
Hi all, Is this valid? I do not find the case in the standard: void foo( int ) {} #define FOO foo int main() {
1
by: Alex | last post by:
Hello all, I have a very stupid problem that is driving me crazy...so plz if anyone ever saw this, I would like him to help me :) I have static MFC application in MSVC++ 6.0 (named Example)....
4
by: nick4ng | last post by:
I need to do something like this #define P1(x) int x##__LINE__ = __LINE__; int main(int argc, char* argv) { P1(a); P1(a); }
3
by: Ernie.Pasveer | last post by:
Hi All, Is there a way to create a macro called #redefine that will allow redefinition without having to use #ifdef/#undef For example, I'd like to do something like this : #define THING ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
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,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

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.