473,516 Members | 2,956 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Macro Expansion

Hello All,

I am trying to get a cut down version of preprocessor output. Let me
make myself clear with a sample:
************************************************** *************************
/*file x.c */
#include <stdio.h>

int main ()
{
int i = 10;
#ifdef TEST
i = i +10;
#else
i = i -10;
#endif
printf("The value of i = %d \n",i);
}

************************************************** ***********************
If I take the preprocessor output for the above file, the output file
will contain huge amount of code as the contents of all the header
files are dumped into output code.

What I am looking at is a output of this nature (if TEST is not
defined)
************************************************** *******************
#include <stdio.h>

int main ()
{
int i = 10;
i = i -10;
printf("The value of i = %d \n",i);
}
************************************************** *******************

Is it possible to get a output of this nature. Is there any way I can
ask the preprocessor not to dump the header file contents, or is there
any other tool available which can serve this purpose?

Any help in this regard is greatly appreciated.

Thanks
-Vittal
Nov 14 '05 #1
4 1868


Vittal wrote:
Hello All,

I am trying to get a cut down version of preprocessor output. [...]


This is Question 10.18 in the comp.lang.c Frequently
Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

--
Er*********@sun.com

Nov 14 '05 #2
On 22 Mar 2005 07:13:11 -0800, Vittal
<vs*********@yahoo.com> wrote:
I am trying to get a cut down version of preprocessor output. Let me
make myself clear with a sample:
************************************************** *************************
/*file x.c */
#include <stdio.h>

int main ()
{
int i = 10;
#ifdef TEST
i = i +10;
#else
i = i -10;
#endif
printf("The value of i = %d \n",i);
}

************************************************** ***********************
If I take the preprocessor output for the above file, the output file
will contain huge amount of code as the contents of all the header
files are dumped into output code.

What I am looking at is a output of this nature (if TEST is not
defined)
************************************************** *******************
#include <stdio.h>

int main ()
{
int i = 10;
i = i -10;
printf("The value of i = %d \n",i);
}
************************************************** *******************

Is it possible to get a output of this nature. Is there any way I can
ask the preprocessor not to dump the header file contents, or is there
any other tool available which can serve this purpose?


It will be specific to the preprocessor (indeed the C standard doesn't
mandate that the preprocessor stage be able to produce any output at
all, it could keep it all in memory for instance). Some preprocessors
do things like putting the line number at the start of each line, or
inserting #line directives or other oddities.

Since yours is fairly 'clean', though, the easiest way to do it is to
put some marker after the #include files:

#include <stdio.h>

/* LOAD oF RuBbIsH which WON't aPPear aNyWherE ELSE */

and then post-process the resulting file and cut out everything before
the marker line. On a *ix system I'd use sed, for example:

gcc -E x.c | sed '1,/LOAD oF RuBbIsH which WON't aPPear aNyWherE ELSE/d'

If your preprocessor inserts lines like

#line 123 "stdio.h"

then you could write a more intelligent post-processor (I'd use Perl or
AWK) which keeps track of which file produced the output and only output
that belonging to the top-level source. For instance, gcc (version 3.3.5)
produces output like:

# 1 "x.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "x.c"

char x;

# 1 "1.h" 1

char x1;
# 1 "11.h" 1
char x11;
# 4 "1.h" 2
# 1 "12.h" 1
char x12;
# 5 "1.h" 2
char x1_end;
# 5 "x.c" 2
# 1 "2.h" 1

char x2;
# 1 "21.h" 1
char x21;
# 4 "2.h" 2
# 1 "22.h" 1
char x22;
# 5 "2.h" 2
char x2_end;
# 6 "x.c" 2

char x_end;

(Sorry, I wasn't very inventive with the file or variable names!)

With system includes it puts more digits on the end of the # lines, I
have no idea what they mean. Anyway, you can see that by recognising
the string with the source file name and only doing output when the last
string matches the top file name you could extract only the code you
want...

Chris C
Nov 14 '05 #3
Chris Croughton wrote:
On 22 Mar 2005 07:13:11 -0800, Vittal wrote:
I am trying to get a cut down version of preprocessor output. [...]

[...]
Since yours is fairly 'clean', though, the easiest way to do it is to
put some marker after the #include files:

#include <stdio.h>

/* LOAD oF RuBbIsH which WON't aPPear aNyWherE ELSE */

and then post-process the resulting file and cut out everything before
the marker line. [...]


If the implementation makes the preprocessor's "output"
available (not guaranteed, as you note), the original comments
are not likely to be present in it. Comments disappear in
translation phase 3, before preprocessing directives and macro
expansions are processed. A better marker would be something
you're sure will survive past phase 4, like

char *delete_thru_here = "LoAd Of rUbBiSh";

There's still a problem, though, and it's a pretty bad
one. Even though this technique lets you snip away everything
the headers injected before the marker, the effects of any
macros defined in those headers will still appear in the
preprocessed source that follows. On one compiler I happen
to have handy,

#include <stdio.h>
int main(void) {
fputs ("Hello, world!\n", stderr);
return 0;
}

becomes (after preprocessing and snipping)

int main(void) {
fputs ("Hello, world!\n", (&__dj_stderr));
return 0;
}

Observe that the portable identifier `stderr' has been
replaced by a non-portable expression -- it happens to be
correct for the system at hand, but this transformed source
is no longer portable. Similar problems can be expected
with any other header-defined macros: INT_MAX, setjmp, ERANGE,
offsetof, ... In fact, all standard library functions are
subject to this sort of mangling, since the implementation is
permitted to define "masking" macros for them.

The compiler's job is to transform portable (we hope)
source code into a non-portable construct specialized for one
implementation. The preprocessor performs part of that
specialization, and its output has usually lost a good deal
of the portability the original source may have had. This
makes the "run it through the preprocessor and then fool
around with the output" strategy problematic at best.

--
Eric Sosman
es*****@acm-dot-org.invalid

Nov 14 '05 #4
On Wed, 23 Mar 2005 09:04:43 -0500, Eric Sosman
<es*****@acm-dot-org.invalid> wrote:
Chris Croughton wrote:
On 22 Mar 2005 07:13:11 -0800, Vittal wrote:
I am trying to get a cut down version of preprocessor output. [...] > [...]
Since yours is fairly 'clean', though, the easiest way to do it is to
put some marker after the #include files:

#include <stdio.h>

/* LOAD oF RuBbIsH which WON't aPPear aNyWherE ELSE */
>
and then post-process the resulting file and cut out everything before
the marker line. [...]


If the implementation makes the preprocessor's "output"
available (not guaranteed, as you note), the original comments
are not likely to be present in it. Comments disappear in
translation phase 3, before preprocessing directives and macro
expansions are processed. A better marker would be something
you're sure will survive past phase 4, like

char *delete_thru_here = "LoAd Of rUbBiSh";


You're right, and looking at a script I had to do it I find it was
actually using:

typedef int This_Is_The_Start_Of_The_Program;

I typed my response from memory...
There's still a problem, though, and it's a pretty bad
one. Even though this technique lets you snip away everything
the headers injected before the marker, the effects of any
macros defined in those headers will still appear in the
preprocessed source that follows. On one compiler I happen
to have handy,

#include <stdio.h>
int main(void) {
fputs ("Hello, world!\n", stderr);
return 0;
}

becomes (after preprocessing and snipping)

int main(void) {
fputs ("Hello, world!\n", (&__dj_stderr));
return 0;
}
And worse.
The compiler's job is to transform portable (we hope)
source code into a non-portable construct specialized for one
implementation. The preprocessor performs part of that
specialization, and its output has usually lost a good deal
of the portability the original source may have had. This
makes the "run it through the preprocessor and then fool
around with the output" strategy problematic at best.


I got the impression that the OP's requirement was to inspect the
output, rathre than use it as a basis for anything portable. I have
many times used the preprocessor output when something is screwy (often
an error message which doesn't make sense) to find out what exactly is
being substituted (the GCC switch which leaves #defines in the output is
useful).

My XCPP is an alternative if what is wanted is to replace only selected
defines and remove constant preprocessor conditionals...

Chris C
Nov 14 '05 #5

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

Similar topics

25
3211
by: Andrew Dalke | last post by:
Here's a proposed Q&A for the FAQ based on a couple recent threads. Appropriate comments appreciated X.Y: Why doesn't Python have macros like in Lisp or Scheme? Before answering that, a clarification on what 'macro' means. A Lisp macro is a way of modifying code when that code is first defined. It can rearrange the structure of the...
699
33329
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro capabilities, unfortunately. I'd like to know if it may be possible to add a powerful macro system to Python, while keeping its amazing syntax, and if it...
3
2061
by: Caleb Hattingh | last post by:
Hi Here is a script I want to be able to write (explanation appears after): *** start of script *** import MyCustomMacroLib # This does the magic I would like help for. # This is not python, but the module imported above # will use this block internally and prevent it
3
2601
by: John | last post by:
Please, consider this macro: #define mymacro(arg1, arg2) arg1 and arg2 Then it is used: mymacro(boys, girls) How is its expansion?
10
2399
by: Karim Thapa | last post by:
Why following macro does not work? #define removebrace(x) x void Foo(int a, int b, char *txt, int d, int e); main() {
5
1995
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() {
2
2194
by: talkaboutquality | last post by:
Need to define a macro as, say, #ifdef NEED_FUNCTION foo(x) #else #endif
6
2290
by: jason | last post by:
Hi, I learned my lesson about passing pointers, but now I have a question about macros. Why does the function work and the MACRO which is doing the same thing on the surface, does not work in the following small example ? #include <stdio.h>
5
6279
by: Francois Grieu | last post by:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at #define a(b) b int main(void){return a( #if 0 #endif 0);} More generally, this compiler seems confused by any preprocessing directive in the middle of macro arguments, which comes handy e.g. to
6
6962
by: Bing | last post by:
Hi folks, Is there a way to define a macro that may contain #include directive in its body. If I just put the "#include", it gives error C2162: "expected macro formal parameter" since here I am not using # to concatenate strings. If I use "\# include", then I receive the following two errors: error C2017: illegal escape sequence...
0
7182
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7408
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7142
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
1
5110
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
4773
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3259
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1624
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
825
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
488
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.