a.h:
#define A(name, val)
a.c:
#undef A
#define A(name, val)\
{(CONST text *)name, (CONST struct a*)val}
#undef A
#define A(name, val)\
// something else here
What is the purpose of undefining a macro? As there is no conditional
compilation around those #define&#undefine, what is going on here?
>a.c:
>
>#undef A
>#define A(name, val)\
> {(CONST text *)name, (CONST struct a*)val}
#include <b.h>
>
>#undef A
>#define A(name, val)\
> // something else here
#include <b.h>
Needless to add that b.h includes a.h.
Returning to a low level language with macros -- what a refresher!
In article <bdf69bdf.02010...@posting.google.com>, Mikito Harakiri
says...
-madhusudan
Mikito Harakiri wrote:
> >What is the purpose of undefining a macro? As there is no conditional
> >compilation around those #define&#undefine, what is going on here?
--
-madhusudan
Ericsson Inc
work :- 805-562-6066
The most common use is probably to avoid namespace conflicts. For
example, if you need a header file that also includes declarations
you don't want, you might write:
#include "foo.h"
#undef PI
#define PI 3
to avoid compiler errors.
I am currently using it to allow a multiple-parameter macro to be
redefined as required to yield subsets of the parameters in a
number of different places. In the code I'm working with at present,
there is a host section with several threads and an embedded section,
with RPC messages flying between them, so sharing the data from one
place is out of the question. I'm strongly averse to the idea of
putting in all the data everywhere it's defined as well. As a suitably
munged example:
master_file.h:
#define MY_MACRO(val_name, value, short_name, description, other_val) \
{ val_name, value, short_name, description, other_val }
#define SET_1 \
MY_MACRO(val1, 0x00000001, "FirstVal", "This is the first val", 2), \
MY_MACRO(val2, 0x00000002, "SecondVal", "This is the second val", 4)
#undef MY_MACRO
#define MY_MACRO(val_name, value, short_name, description, other_val) \
val_name = value
enum value_set_1
{
SET_1
};
...
macro_names.c:
#include "master_file.h"
#undef MY_MACRO
#define MY_MACRO(val_name, value, short_name, description, other_val) \
short_name
const char* names1[] =
{
SET_1
}
...
macro_descriptions.c:
#include "master_file.h"
#undef MY_MACRO
#define MY_MACRO(val_name, value, short_name, description, other_val) \
description
const char* descriptions1[] =
{
SET_1
}
This way, all the information is gathered in one central place (in this
case, master_file.h) and changes to the values in the data set are
automatically reflected everywhere the macro is used.
Oh yes, even the C++ compilers we use accept this with no complaint
with the warnings turned up to the max (-Wall -ansi -pedantic for
the Gnu compilers).
Geoff
--
Geoff Field, Professional geek, amateur stage-levelling gauge.
Spamtraps: geoff...@hotmail.com, gcf...@bigmailbox.net, or
geoff...@great-atuin.co.uk; Real Email: gcfield at optusnet dot com dot au
My band's web page: http://www.geocities.com/southernarea/
I've done something similar, though not as practical!
/*
// hitch_hickers [word]...
//
// Use your towel to dampen any undefined behaviour.
*/
#include <stdio.h>
#include <string.h>
#define blank
#define comma ,
#define semicolon ;
#define command_set(macro, _) \
macro( arthur , "My left arm is missing." ) _ \
macro( zaphod , "It's this wierd casting that freaks me." ) _ \
macro( ford , "Potentially bright lad I thought." ) _ \
macro( marvin , "Don't talk to me about life." ) _ \
macro( trillian , "What with a degree in astrophysics..." ) _ \
macro( guide , "Don't panic!!" ) _ \
macro( earth , "Harmless." ) _ \
macro( petunias , "Oh no, not again." ) _ \
macro( mice , "What have men got to do with it?" ) _ \
macro( deep_thought , "42." )
#define as_enum( name, quote ) name##_ce
#define as_prototype( name, quote ) void do_##name(void)
#define as_struct( name, quote ) { #name, do_##name }
#define as_function( name, quote ) \
void do_##name(void) { \
printf(#name ": %s\n", quote); \
}
enum command_e {
command_set(as_enum, comma),
commands_k
};
command_set(as_prototype, semicolon);
typedef struct command_s command_t;
struct command_s {
char *name;
void (*function)(void);
};
command_t command_list[] = { command_set(as_struct, comma) };
command_set(as_function, blank)
int main(int argc, char *argv[]) {
if (argc) {
while (argv++, --argc) {
int i;
for (i = 0; i < commands_k; i++)
if (strcmp(*argv, command_list[i].name) == 0) {
command_list[i].function();
break;
}
if (i == commands_k)
printf("%s? I haven't got to that page!!\n", *argv);
}
}
command_list[deep_thought_ce].function();
return 0;
}
But don't try and maintain this code without a babel fish in your ear! ;)
--
Peter