| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| Hi, I've a question about preprocessing of code. Let's say I've these three files: // File: b.h #ifndef __MY_B_H #define __MY_B_H typedef int int_least8_t; typedef unsigned int uint_least8_t; #endif ///////////// // File b.c #include "b.h" int main() { return 0; } ///////////// // File a.c #include "b.h" int foo() { return; } ///////////// I would like to get the preprocessed file where all includes and macros are resolved. My idea was to use "gcc -E b.c a.c". I get: # 1 "b.c" # 1 "<built-in>" # 1 "<command line>" # 1 "b.c" # 1 "b.h" 1 typedef int int_least8_t; typedef unsigned int uint_least8_t; # 2 "b.c" 2 int main() { return 0; } # 1 "a.c" # 1 "<built-in>" # 1 "<command line>" # 1 "a.c" # 1 "b.h" 1 typedef int int_least8_t; typedef unsigned int uint_least8_t; # 2 "a.c" 2 int foo() { return; } What I don't understand is why the header file was included twice. Since __MY_B_H was defined while including b.h from b.c I would assume that a.c would not include b.h any more. However, this happens. Why? And how can I achieve to have b.h included exactly once? Regards, Tim |
|
#2
| |||
| |||
| Tim Frink <plfriko@yahoo.de> writes: > I've a question about preprocessing of code. Let's say I've these > three files: > > // File: b.h > #ifndef __MY_B_H > #define __MY_B_H > > typedef int int_least8_t; > typedef unsigned int uint_least8_t; > > #endif > ///////////// > > // File b.c > #include "b.h" > > int main() > { > return 0; > } > ///////////// > > // File a.c > #include "b.h" > > int foo() > { > return; > } > ///////////// > > I would like to get the preprocessed file where all includes and > macros are resolved. My idea was to use "gcc -E b.c a.c". > > I get: > > # 1 "b.c" > # 1 "<built-in>" > # 1 "<command line>" > # 1 "b.c" > # 1 "b.h" 1 > > typedef int int_least8_t; > typedef unsigned int uint_least8_t; > # 2 "b.c" 2 > > int main() > { > return 0; > } > # 1 "a.c" > # 1 "<built-in>" > # 1 "<command line>" > # 1 "a.c" > # 1 "b.h" 1 > > typedef int int_least8_t; > typedef unsigned int uint_least8_t; > # 2 "a.c" 2 > > int foo() > { > return; > } > > > What I don't understand is why the header file was included twice. > Since __MY_B_H was defined while including b.h from b.c I would assume > that a.c would not include b.h any more. However, this happens. > Why? Each source file processed by gcc (a.c and b.c) starts off with a "clean slate" -- no macros defined from processing one source file carry over to subsequent ones. The include guard (the #ifndef trick) works only when a single source ends up including b.h by two different routes (say by including x.h and y.h both of which include b.h). > And how can I achieve to have b.h included exactly once? I am tempted to say, stop wanting that. Even in you get something that works, it will interact badly with build tools like make that can compile source files in any order. What is the coding problem that you are trying to solve this way? -- Ben. |
|
#3
| |||
| |||
| "Tim Frink" <plfriko@yahoo.de> wrote in message news:g93uu1$6ht$1@janice.cs.uni-dortmund.de... > I've a question about preprocessing of code. Let's say I've these > three files: > > // File: b.h > // File b.c > #include "b.h" > // File a.c > #include "b.h" > What I don't understand is why the header file was included twice. > Since __MY_B_H was defined while including b.h from b.c I would assume > that a.c would not include b.h any more. However, this happens. > Why? > And how can I achieve to have b.h included exactly once? The #include statement is not smart. If you think of an include file as a giant macro, then clearly everywhere you repeat the include, the file contents will be expanded at that point. Anyway you've included b.h just once in each module, which is what counts. But you seem to want to concatenate all the source files, while expanding each include. I'm not sure the result will be meaningful, because identical definitions in each module will also be duplicated. So if you have sources containing "void foo(){}" in one file, and "void foo(){}" in another, the result will be: "void foo(){} void foo(){};". What is it you're trying to achieve? -- Bartc |
|
#4
| |||
| |||
| First of all, sorry for the double post. > I am tempted to say, stop wanting that. Even in you get something > that works, it will interact badly with build tools like make that can > compile source files in any order. What is the coding problem that > you are trying to solve this way? I'll answer here to all the other posts: I have a prototype program analysis tool that only accepts single files. The benchmark I wanted to evaluate however consists of multiple compilation units. So my idea was to "paste" all files automatically into one file via a preprocessor. But this doesn't seem to work. However, I'm still somewhat surprised because "gcc a.c b.c" works fine. If each function is handled separately I would expect to get some error of type "multiple definition of" int_least8_t ... Why does this not happen? |
|
#5
| |||
| |||
| "Tim Frink" <plfriko@yahoo.de> wrote in message news:6hlrfrFmug3eU1@mid.individual.net... > First of all, sorry for the double post. > >> I am tempted to say, stop wanting that. Even in you get something >> that works, it will interact badly with build tools like make that can >> compile source files in any order. What is the coding problem that >> you are trying to solve this way? > > I'll answer here to all the other posts: I have a prototype program > analysis tool that only accepts single files. The benchmark I wanted > to evaluate however consists of multiple compilation units. So my > idea was to "paste" all files automatically into one file via a > preprocessor. But this doesn't seem to work. > > However, I'm still somewhat surprised because > "gcc a.c b.c" works fine. If each function is handled separately > I would expect to get some error of type "multiple definition of" > int_least8_t ... Why does this not happen? Gcc works a file at a time. Without being an expert gcc user, I think that gcc a.c b.c is equivalent to: gcc -c a.c gcc -c b.c followed by linking (and typedef identifiers are not linked between modules). I'm sure that there must be some tool that combines multiple .c files into one large file suitable for input for your application. Either that or concatenate all the files then edit manually to fix clashes and other errors. -- Bartc |
|
#6
| |||
| |||
| Tim Frink <plfriko@yahoo.de> writes: > First of all, sorry for the double post. > >> I am tempted to say, stop wanting that. Even in you get something >> that works, it will interact badly with build tools like make that can >> compile source files in any order. What is the coding problem that >> you are trying to solve this way? > > I'll answer here to all the other posts: I have a prototype program > analysis tool that only accepts single files. The benchmark I wanted > to evaluate however consists of multiple compilation units. So my > idea was to "paste" all files automatically into one file via a > preprocessor. But this doesn't seem to work. No, it won't work. In C the file boundaries are important. If you concatenate sources the result not likely to be legal C and crucial information will have been lost. > However, I'm still somewhat surprised because > "gcc a.c b.c" works fine. If each function is handled separately > I would expect to get some error of type "multiple definition of" > int_least8_t ... Why does this not happen? Linking two compiled files (C calls the compilation units), each of which contains a typedef for this type does not result in anything being multiply defined. Essentially, a typedef is not visible outside of the unit that contains it. If the same type name was defined twice in the same compilation unit, or two separate compilation units defined the same object with external linkage, you would get an error. -- Ben. |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.