By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,145 Members | 1,151 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,145 IT Pros & Developers. It's quick & easy.

Preprocessor directive

P: n/a
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how?

/If/ my question above isn't very clear you can refer to
the following example.

eg cosider 2 files sample.c and sample.h

sample.h
#define BLAH 10

sample.c
/* This should print 10 */
printf("\n %d ", BLAH);

func1();

printf("\n %d ", BLAH);

func1()
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

}

Thanks,
Nov 13 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a
What are you trying to accomplish ? The pre-processor simply expands your
macro when you compile your code. So, if you were to compile a separate .c
file that included 'sample.h', it would only see the definition of BLAH in
sample.h (which is 10). BLAH does not have local scope. As far as the
compiler is concerned, the argument to the last printf() statement is the
constant 15. Explain what you are trying to do and I can provide some
assistance.

"Trying_Harder" <fr***********@yahoo.com> wrote in message
news:b0**************************@posting.google.c om...
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how?

/If/ my question above isn't very clear you can refer to
the following example.

eg cosider 2 files sample.c and sample.h

sample.h
#define BLAH 10

sample.c
/* This should print 10 */
printf("\n %d ", BLAH);

func1();

printf("\n %d ", BLAH);

func1()
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

Nov 13 '05 #2

P: n/a
Trying_Harder wrote:
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how?
Macros are not `scoped'. Preprocessing takes place *before* scope of
any kind is established.
/If/ my question above isn't very clear you can refer to
the following example.

eg cosider 2 files sample.c and sample.h

sample.h
#define BLAH 10

sample.c
/* This should print 10 */
printf("\n %d ", BLAH);

func1();

printf("\n %d ", BLAH);

func1()
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

}


`BLAH' will be replaced by `15' for the rest of the translation unit.

HTH,
--ag

--
Artie Gold -- Austin, Texas
Oh, for the good old days of regular old SPAM.

Nov 13 '05 #3

P: n/a
Trying_Harder wrote:

Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how?
The scope of a macro definition lasts from the #define
to the #undef, or to the end of the translation unit. Macro
scopes do not nest, so there's no way to "push" a replacement
definition and then "pop" the original.
/If/ my question above isn't very clear you can refer to
the following example.

eg cosider 2 files sample.c and sample.h

sample.h
#define BLAH 10

sample.c
/* This should print 10 */
printf("\n %d ", BLAH);

func1();

printf("\n %d ", BLAH);

func1()
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

}


The numbers output would be 10, 15, and 10, in that order.
BLAH does not have "a local scope" in func1(); BLAH remains
defined as 15 all the way to the end of the compilation.

--
Er*********@sun.com
Nov 13 '05 #4

P: n/a
Trying_Harder <fr***********@yahoo.com> wrote:
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how? /* This should print 15, but BLAH has a local scope */


preprocessor directives don't have scope. The preprocessor will go from
the beginning of the program to the end and make replacements as necessary.
The first two BLAH's are being replaced by 10 because when test.h is
#included, it is #defined to 10. The BLAH in func1 was replaced by 15
because it was defined after main. If you put its declaration above main
then it will print 15 for all of them. Keep in mind, the preprocessor
is *not* operated at run-time, it is done *before* compilation.

What are you trying to accomplish? Even if you could pull that off you
probably shouldn't.

--
Harrison Caudill | .^ www.hypersphere.org
Computer Science & Physics Double Major | | Me*Me=1
Georgia Institute of Technology | '/ I'm just a normal guy
Nov 13 '05 #5

P: n/a
>
preprocessor directives don't have scope. The preprocessor will go from
the beginning of the program to the end and make replacements as necessary.
The first two BLAH's are being replaced by 10 because when test.h is
#included, it is #defined to 10. The BLAH in func1 was replaced by 15
because it was defined after main. If you put its declaration above main
then it will print 15 for all of them. Keep in mind, the preprocessor
is *not* operated at run-time, it is done *before* compilation.

What are you trying to accomplish? Even if you could pull that off you
probably shouldn't.
Let me start off with a thanks to all.
Actually, I have 3 modes the program can execute in, for example sake
`a', `b' and `c'. Now in each of these modes value of a particular
preprocessor macro is different, but the program can execute only in
a one mode in one execution.
Decision of what its value is, is taken soon after the program begins,
but I am doing this part in a function because of my aim to keep the
main function "light".

So func1() is where I am assigning the value to these macros depending
on `argv'.
One solution is to return a value from func1() hinting something about
the mode and #defining in main.
But, can't this be done in func1()?

Btw, in one of the other posts

<quoting Eric Sosman>
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

}

The numbers output would be 10, 15, and 10, in that order.
BLAH does not have "a local scope" in func1(); BLAH remains
defined as 15 all the way to the end of the compilation.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If don't find this answer not convincing. If this was true then why
is the 3rd `printf' (in main) printing out 10 ? According to this
explanation it should print out 15 everywhere (after this "redefinition")
regardless of the scope.

Thank you for your help, I would really appreciate if someone could
refer me to some online resources containing preprocessor directives
explained in detail.

Thanks,
Nov 13 '05 #6

P: n/a
Charles Harrison Caudill <ku*****@myrna.cc.gatech.edu> wrote in message news:<bl**********@solaria.cc.gatech.edu>...
Trying_Harder <fr***********@yahoo.com> wrote:
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how?
/* This should print 15, but BLAH has a local scope */


preprocessor directives don't have scope. The preprocessor will go from
the beginning of the program to the end and make replacements as necessary.
The first two BLAH's are being replaced by 10 because when test.h is
#included, it is #defined to 10. The BLAH in func1 was replaced by 15
because it was defined after main. If you put its declaration above main
then it will print 15 for all of them. Keep in mind, the preprocessor
is *not* operated at run-time, it is done *before* compilation.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^
What happens if macro is decleared in main().Just a doubt, that is all.
#define blaa 10
void fun(void)
{
printf("%d\n",blaa);
#ifdef blaa
#undef blaa
#define blaa 90
#endif
printf("now blaa is = %d\n",blaa);
}
int main(void)
{
fun();
#ifdef blaa
#undef blaa
#define blaa 98
#endif
printf("now blaa has %d\n",blaa);
return 0;
}

What are you trying to accomplish? Even if you could pull that off you
probably shouldn't.

Nov 13 '05 #7

P: n/a
fr***********@yahoo.com (Trying_Harder) wrote in message > >
If don't find this answer not convincing. If this was true then why

^^^

Sorry about the typo there. I meant to say "I dont find this answer
convincing".

p.s: Can someone please attend to my question above?

Thanks,
Nov 13 '05 #8

P: n/a
Trying_Harder wrote:
p.s: Can someone please attend to my question above?


Here's the original code:

[Trying_Harder]
| sample.h
| #define BLAH 10
|
| sample.c
| /* This should print 10 */
| printf("\n %d ", BLAH);
|
| func1();
|
| printf("\n %d ", BLAH);
|
| func1()
| {
| #undef BLAH
| #define BLAH 15
| /* This should print 15, but BLAH has a local scope */
| printf("\n %d ", BLAH);
|
| }

Here's the (correct) answer you don't find convincing:

[Eric Sosman]
|> The numbers output would be 10, 15, and 10, in that order.
|> BLAH does not have "a local scope" in func1(); BLAH remains
|> defined as 15 all the way to the end of the compilation.

Here's the question I think you're referring to:

[Trying_Harder]
| If don't find this answer not convincing. If this was true then why
| is the 3rd `printf' (in main) printing out 10 ? According to this
| explanation it should print out 15 everywhere (after this "redefinition")
| regardless of the scope.

Preprocessor replacement works on the text of the source file, so
occurrences of "BLAH" in the lines following the "#undef", "#define"
directives are replaced with "15" during an early stage of
compilation. Occurrences of "BLAH" before this (but following the
first "#define") are replaced with "10". After all this has taken place
the output from "sample.c" looks something like this:

printf("\n %d ", 10);

func1();

printf("\n %d ", 10);

func1()
{

printf("\n %d ", 15);

}

Note that this all takes place at "compile-time", i.e. before the
program is run at all. Further stages of compilation translate your
program into some sort of executable format, by which point there is
no trace of "#define" or "BLAH" left; the preprocessor directives have
already been executed and only "runnable" code remains.

"BLAH" is not like a variable, which is initialised at runtime.
"func1()" does not change the value of "BLAH". The fact that the
second "#define" is textually inside the body of "func1()" is
irrelevant; there is nothing left of "BLAH" or its various definitions
by the time "func()" is called.

Jeremy.
Nov 13 '05 #9

P: n/a
da***********@yahoo.com wrote:
What happens if macro is decleared in main().Just a doubt, that is all.
Nothing special about that, the preprocessor does not care if it's in
main() or somewhere else:
#define blaa 10
void fun(void)
{
printf("%d\n",blaa);
This would be replaced by the preprocessor by

printf("%d\n",10);
#ifdef blaa
#undef blaa
#define blaa 90
#endif
Since 'blaa' was already defined it now would be redefined to 90
printf("now blaa is = %d\n",blaa);
so this would end up as

printf("now blaa is = %d\n",90);
}
int main(void)
{
fun();
fun will now print out

10
90

(BTW this would also happen if you would redefine 'blaa' before the
call of fun() since the preprocessor has already done it's work on
the body of fun().)
#ifdef blaa
#undef blaa
#define blaa 98
#endif
And this will redefine 'blaa' to 98
printf("now blaa has %d\n",blaa);
so here you get
printf("now blaa has %d\n",98); return 0;
}

Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Je***********@physik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oerring
Nov 13 '05 #10

P: n/a
On Thu, 2 Oct 2003 16:18:44 UTC, fr***********@yahoo.com
(Trying_Harder) wrote:
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how?


1. a macro has only translation unit scope. It exists from tjhe point
on it gets #define'd unless the point it gets #undef-ined or at end of
the translation unit. It exists only until the preprocessor has made
its text replacements. So you can't depend on a macro in runtime as
any text replacement is done before the compiler will start
transationg the source to something else.

So whenever your code has a decision at runtime there is no help on a
macro. Use native C code (even written as a number of statements under
a macro name) to decide which option the user likes.

You may even compose macros at translation time - but however that
will be resolved long before the compiler itself sees the macro.

Use #undef to undefine a macro when its body looses its meaning, use
another #define to redifine it thereafter with anything you means the
macro has to do now, but as the proprocessor does nothing than to
replace some text with another text it would not be a solution to
modify your code at runtime.

You can do many very complicate things with your source with macros at
compile time - but even before the compiler itself starts to translate
the source to its itermediade code the time is over to play with the
preprocessor. So no parameter you may give your program in runtime can
have a bit effect on a macro.

--
Tschau/Bye
Herbert

eComStation 1.1 Deutsch wird jetzt ausgeliefert!
Nov 13 '05 #11

P: n/a
fr***********@yahoo.com (Trying_Harder) wrote in message news:<b0**************************@posting.google. com>...
fr***********@yahoo.com (Trying_Harder) wrote in message > >
If don't find this answer not convincing. If this was true then why

^^^

Sorry about the typo there. I meant to say "I dont find this answer
convincing".

p.s: Can someone please attend to my question above?

Thanks,


Here's your code before preprocessing:

sample.h
#define BLAH 10

sample.c
/* This should print 10 */
printf("\n %d ", BLAH);

func1();

printf("\n %d ", BLAH);

func1()
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

}

Here's your code *after* preprocessing:

sample.c
printf("\n %d ", 10);

func1();

printf("\n %d ", 10);

func1()
{
printf("\n %d ", 15);

}

Does that help?

The preprocessor does not obey scope rules. It doesn't know what
scope is. As far as it's concerned, your source code is just a stream
of text that it scans from top to bottom, doing replacements as
necessary.
Nov 13 '05 #12

P: n/a
da***********@yahoo.com wrote in message news:<a3**************************@posting.google. com>...
Charles Harrison Caudill <ku*****@myrna.cc.gatech.edu> wrote in message news:<bl**********@solaria.cc.gatech.edu>...
Trying_Harder <fr***********@yahoo.com> wrote:
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how? /* This should print 15, but BLAH has a local scope */
preprocessor directives don't have scope. The preprocessor will go from
the beginning of the program to the end and make replacements as necessary.
The first two BLAH's are being replaced by 10 because when test.h is
#included, it is #defined to 10. The BLAH in func1 was replaced by 15
because it was defined after main. If you put its declaration above main
then it will print 15 for all of them. Keep in mind, the preprocessor
is *not* operated at run-time, it is done *before* compilation.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^
What happens if macro is decleared in main().Just a doubt, that is all.


No, don't even think of them as being "declared" anywhere. Macros are
not variables. They don't act like variables. The preprocessor scans
the source file from top to bottom, replacing text as it goes.

#define BLAH 10
/* every occurence of BLAH from this point is replaced with 10 */
#undef BLAH
#define BLAH 20
/* every occurence of BLAH from this point is replaced with 20 */

It doesn't matter whether the preprocessor directive is embedded
within the text for a function definition or not. The preprocessor
doesn't understand what functions are, what scope is, or anything
else. All it sees is a stream of text.

There is no effective difference between:

#define BLAH 10
void f(void)
{
printf ("%d\n", BLAH);
}

void g(void)
{
printf ("%d\n", BLAH);
}

and:

void f(void)
{
#define BLAH 10
printf ("%d\n", BLAH);
}

void g(void)
{
printf ("%d\n", BLAH);
}

If you try something like:

void f(void)
{
printf ("%d\n", BLAH);
}

#define BLAH 10
int main (void)
{
f();
return 0;
}

the preprocessor will yak at you because BLAH hasn't been defined
before it's used in f(). The preprocessor goes straight from top to
bottom.
BLAH is not local to f() in the second example. It's not local to
anything.
Back to your example, before preprocessing:
#define blaa 10
void fun(void)
{
printf("%d\n",blaa);
#ifdef blaa
#undef blaa
#define blaa 90
#endif
printf("now blaa is = %d\n",blaa);
}
int main(void)
{
fun();
#ifdef blaa
#undef blaa
#define blaa 98
#endif
printf("now blaa has %d\n",blaa);
return 0;
}

After preprocessing: void fun(void)
{
printf("%d\n",10);
printf("now blaa is = %d\n",90);
}
int main(void)
{
fun();
printf("now blaa has %d\n",98);
return 0;
}

Nov 13 '05 #13

P: n/a
bd
Trying_Harder wrote:

preprocessor directives don't have scope. The preprocessor will go from
the beginning of the program to the end and make replacements as
necessary. The first two BLAH's are being replaced by 10 because when
test.h is
#included, it is #defined to 10. The BLAH in func1 was replaced by 15
because it was defined after main. If you put its declaration above main
then it will print 15 for all of them. Keep in mind, the preprocessor
is *not* operated at run-time, it is done *before* compilation.

What are you trying to accomplish? Even if you could pull that off you
probably shouldn't.


Let me start off with a thanks to all.
Actually, I have 3 modes the program can execute in, for example sake
`a', `b' and `c'. Now in each of these modes value of a particular
preprocessor macro is different, but the program can execute only in
a one mode in one execution.
Decision of what its value is, is taken soon after the program begins,
but I am doing this part in a function because of my aim to keep the
main function "light".

So func1() is where I am assigning the value to these macros depending
on `argv'.
One solution is to return a value from func1() hinting something about
the mode and #defining in main.
But, can't this be done in func1()?

Btw, in one of the other posts

<quoting Eric Sosman>
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

}

The numbers output would be 10, 15, and 10, in that order.
BLAH does not have "a local scope" in func1(); BLAH remains
defined as 15 all the way to the end of the compilation.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If don't find this answer not convincing. If this was true then why
is the 3rd `printf' (in main) printing out 10 ? According to this
explanation it should print out 15 everywhere (after this
"redefinition") regardless of the scope.

Thank you for your help, I would really appreciate if someone could
refer me to some online resources containing preprocessor directives
explained in detail.


Preprocessor directives aren't affected at all by normal execution flow -
the definition and redefinition is governed solely by the order they're
listed in the source file. Think of them as search-and-replace, only
automated:

#include <stdio.h>
#define FOO 15

void a(void);
void b(void);

int main() {
printf("%d\n", FOO); /* 15 */
a();
printf("%d\n", FOO); /* 15 */
b();
printf("%d\n", FOO); /* 15 */
return 0;
}

void b(void){
printf("%d\n", FOO); /* 15 */
}

void a(void){
#undef FOO
#define FOO 42
printf("%d\n", FOO); /* 42 */
}

As you can see, even though a() was run before b(), because it's listed
later in the source file, the redefinition does not affect b().
--
If you want your spouse to listen and pay strict attention to every
word you say, talk in your sleep.

Nov 13 '05 #14

P: n/a
Trying_Harder <fr***********@yahoo.com> wrote:
Is it possible to redefine a macro with global scope after
undefining it in a function? If yes, could someone explain
how?

/If/ my question above isn't very clear you can refer to
the following example.

eg cosider 2 files sample.c and sample.h

sample.h
#define BLAH 10

sample.c
/* This should print 10 */
printf("\n %d ", BLAH);

func1();

printf("\n %d ", BLAH);

func1()
{
#undef BLAH
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);

}


If you want to set it back to what it was, for the rest of the
source file following func1, do:

func1()
{
#ifdef BLAH
#define BLAH_OLD BLAH
#undef BLAH
#endif
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);
#undef BLAH
#ifdef BLAH_OLD
#define BLAH BLAH_OLD
#undef BLAH_OLD
#endif
}

- Kevin.

Nov 13 '05 #15

P: n/a
In article <ne********************@tomato.pcug.org.au>
Kevin Easton <kevin@-nospam-pcug.org.au> writes:
If you want to [save and restore the expansion of a #define'd macro]:

func1()
{
#ifdef BLAH
#define BLAH_OLD BLAH
#undef BLAH
#endif
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);
#undef BLAH
#ifdef BLAH_OLD
#define BLAH BLAH_OLD
#undef BLAH_OLD
#endif
}


Unfortunately, this does not work.

In particular, the first (indented) "#define" above defines BLAH_OLD
to expand to the literal text BLAH, not "to whatever BLAH used to
expand to". Then the #undef removes "whatever BLAH used to expand
to", which will never be seen again.

If you have a compiler flag that will dump "preprocessor output"
you can see that this does indeed occur:

% cat t.c
#define X 1

#define SAVE_X X
#undef X
#define X 2
after attempt to save:
uppercase x expands to X
uppercase save_x expands to SAVE_X

#undef X
#define X SAVE_X
#undef SAVE_X
after attempt to restore:
uppercase x expands to X
% cc -E t.c
# 1 "t.c"

after attempt to save:
uppercase x expands to 2
uppercase save_x expands to 2


after attempt to restore:
uppercase x expands to SAVE_X

In order to save the existing expansion of a #define'd identifier,
you would need to cause a logical source line first to be
macro-expanded, and only then interpreted as a "#define" directive;
and the C standards (both C89 and C99) explicitly rule out this
possibility. Thus, this is impossible in Standard C. (There might
be compilers that have a nonstandard trick such as a "#pragma
pushmacro" directive to achieve the goal in a compiler-specific
manner.)
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://67.40.109.61/torek/index.html (for the moment)
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 13 '05 #16

P: n/a
Chris Torek <no****@elf.eng.bsdi.com> wrote:
In article <ne********************@tomato.pcug.org.au>
Kevin Easton <kevin@-nospam-pcug.org.au> writes:
If you want to [save and restore the expansion of a #define'd macro]:

func1()
{
#ifdef BLAH
#define BLAH_OLD BLAH
#undef BLAH
#endif
#define BLAH 15
/* This should print 15, but BLAH has a local scope */
printf("\n %d ", BLAH);
#undef BLAH
#ifdef BLAH_OLD
#define BLAH BLAH_OLD
#undef BLAH_OLD
#endif
}


Unfortunately, this does not work.

In particular, the first (indented) "#define" above defines BLAH_OLD
to expand to the literal text BLAH, not "to whatever BLAH used to
expand to". Then the #undef removes "whatever BLAH used to expand
to", which will never be seen again.


I *knew* I should have tested that before I hit enter to post...

The reason I didn't is because I'd just seen this in some code I was
reading at work last week, and didn't think at all about whether it
would really work or not. Oh well, I'm rewriting that entire program at
the moment anyway.

- Kevin.

Nov 13 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.