I have a project in C that I need to modify and run. At some point, in a source file I have
#ifndef THE_FLAG
// declare important stuff
#endif
but, I don't know where THE_FLAG is #included from. It is not defined in my project, and it is hidden somewhere in external library.
I tried gcc -M but it shows the headers, without information if it was included directly or somewhere higher in the include hierarchy.
The project is too complicated to track all the dependencies by hand. It is build with ./configure && make.
Question: how to track this external dependency?
Try compiling with gcc -E. This will tell gcc to stop at the preprocessing stage. As part of that, it will tell you where all the #defines came from.
Note that this will create a text file, not a .o file.
You can get gcc to tell you exactly where the flag is defined by redefining it for test purposes, e.g.
#include <limits.h>
#define INT_MAX 42
int f(void)
{
return INT_MAX;
}
will make gcc complain
main.c:4:0: warning: "INT_MAX" redefined [enabled by default]
#define INT_MAX 42
^
In file included from main.c:2:0:
/usr/lib/gcc/x86_64-redhat-linux/4.8.1/include/limits.h:120:0: note: this is the location of the previous definition
#define INT_MAX __INT_MAX__
^
The same strategy also works well for finding struct definitions (very useful in case you have several architect specific header files and you are not sure which one is actually used!).
#include <stdio.h>
typedef void FILE;
void f(void)
{
}
gives
main.c:3:14: error: conflicting types for ‘FILE’
typedef void FILE;
^
In file included from main.c:1:0:
/usr/include/stdio.h:48:25: note: previous declaration of ‘FILE’ was here
typedef struct _IO_FILE FILE;
^
gcc -E will give us the output after preprocessor. But sometimes it will be difficult for a developer to verify if the .c file is very big and including some big header files. In such cases checking build output will be easier. #warning will print the message as warning during compilation.
#ifndef THE_FLAG
#warning "including ABC stuff"
// declare important stuff
#endif
We can make compiler warnings using #pragma also, but its not platform independent.
#pragma "including ABC stuff"
If we want to stop the compilation if some unwanted macros has been defined somewhere, we can use #error.
#ifdef UNWANTED_FLAG
#error "Build stopped. UNWANTED flag has been defined"
#endif
Related
EDIT : reformulate my question :
In file like delay.h (for avr programming in embedded system) you find this kind of pre-processor define :
#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
# define F_CPU 1000000UL
#endif
It seems quite simple. If nobody defined a value for F_CPU, this will declare 10000000 for it and continue compilation. There is no .c file only a .h file.
Now I have a couple of .c and .h file of my own. And when I try to implement this kind of protection for another value. I get a warning even if I previously declared the value in mu main.c file.
main.c file :
#define BAUDE_RATE_SPEED 115200
#include "uart_ctrl.h"
void main(){
}
uart_ctrl.h file :
#ifndef __UART_CTRL_H__
#define __UART_CTRL_H__
#ifndef BAUDE_RATE_SPEED
#define BAUDE_RATE_SPEED 9600
#warning "BAUDE_RATE_SPEED defined at 9600 in uart_ctrl.h"
#endif
void uart_config();
#endif
uart_ctrl.c file :
#include "uart_ctrl.h"
void uart_config(){
MCU_REGISTER.UART = BAUDE_RATE_SPEED;
}
build error :
Warning #warning "BAUDE_RATE_SPEED defined at 9600 in uart_ctrl.h" [-Wcpp] \uart_ctrl.h Build 1
Why this rise me a warning ? Is it normal and i don't understand behaviours or I missed something ?
Thanks again for your help.
------------- Previous question
Ok, I didn't exactly how to ask this questions. Let me know if you see a better option than the title I set.
On embedded system is very common to declare the mcu frequency with this statement for 20Mhz frequency.
#define F_CPU 20000000UL
And it's common too, to have this kind of check, in files using it. Let say delay.h :
#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
# define F_CPU 1000000UL
#endif
If I define F_CPU in my main or anywhere before including my delay.h the warning does not appear and the the first declared F_CPU value is used.
Now I'm writing my own library, I'm trying to do the same, with the same structure. For example :
#ifndef UART_BAUD_SPEED
/* prevent compiler error by supplying a default */
# warning "UART_BAUD_SPEED not defined bla bla"
# define UART_BAUD_SPEED 115200
#endif
But it trig warning anyway. If my library is .H file only or if this is couple h/c file.
How can I implement the same warning/error protection in my library ? What i'm missing ?
Thanks in advance for your help.
The compiler compiles each file separately. When it compiles main.c, main.c defines BAUDE_RATE_SPEED before it includes uart_ctrl.h. When it compiles uart_ctrl.c, nothing defines BAUDE_RATE_SPEED before uart_ctrl.h, so it is not defined and it gives the warning.
When you run the compiler it has an option to define things automatically before compiling the file, which might be where F_CPU comes from. It would be typical to add -DBAUDE_RATE_SPEED=9600 to the compiler command for all files in the project, instead of defining it separately in each file. If you are using an IDE, you may have to figure out where to enter this in the IDE.
Ok, I found where is my miss-understanding.
as #user253751 said, each files is compiled separately. But this only apply to file with couple .h/.c file. Because the delay.h file is header only file, it is never compiler alone. Only included. So the warning never triggered.
Thanks for your help.
I'm using Keil to code for STM32 microcontrollers. In main.h file, I use this code:
#if defined __has_include //Keil recognizes this preprocessor. If it was unavailable, Keil would have marked it as gray
#if __has_include("Debugg.h")
#include "Debugg.h"
#endif
#endif
This, checks if the Debugg.h file exists. Let's imagine I have a #define in Debugg.h file:
#define DEBUGGING 1
Now, I expect that in main.h, the DEBUGGING is defined. Again main.h:
#if defined __has_include //Keil recognizes this preprocessor. If it was unavailable, Keil would have marked it as gray
#if __has_include("Debugg.h")
#include "Debugg.h"
#endif
#endif
#ifdef DEBUGGING
#define MAIN_DEBUG 1 //This line runs
#else
#define MAIN_DEBUG 0 //Keil IDE mark this line as gray, meaning "unavailable code"
#endif
But, whenever I try to print MAIN_DEBUG or use it, it is 0!
NOTE:
It seems that Keil IDE recognizes the __has_include preprocessor, but the compiler DOES NOT; because when I comment out these lines:
//#if defined __has_include
#if __has_include("Debugg.h")
#include "Debugg.h"
#endif
//#endif
I get these errors:
compiling main.c...
..\Library\main.h(5): error: #59: function call is not allowed in a constant expression
#if __has_include("Debugg.h")
..\Library\main.h(5): error: #31: expression must have integral type
#if __has_include("Debugg.h")
..\Library\main.c: 0 warnings, 2 errors
I also use the default ARM compiler version 5. Any suggestions?
Thanks.
Any suggestions?
Do not use non-portable extensions like __has_include. Build systems are used to detect information about environment, like available headers.
For example, CMake build system has check_include_file that you can check if an include file exists. Then if the include file Debugg.h (why upper+lower case mix?) exists, then add a macro HAS_DEBUGG_H to compilation and if that macro is defined, then include the header.
a libX.c, a libX.h and libX_conf.h file. the checking for Debugg.h is in config file. If it was available, it checks for the prints of a specific thread. If not, debugging is deactivated
That should be done with a macro, not with "detecting header file". There should be a macro, called like LIBX_DEBUG_ENABLE and if defined, libX should output debugging information. I.e. it is a user configuration setting done with a macro, not with deleting a file.
I'm a C newbie and I was just trying to write a console application with Code::Blocks. Here's the (simplified) code:
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "test.c" // include not necessary for error in Code::Blocks
int main()
{
//t = test(); // calling of method also not necessary
return 0;
}
test.c:
void test() {}
When I try to build this program, it gives the following errors:
*path*\test.c|1|multiple definition of `_ test'|
obj\Debug\main.o:*path*\test.c|1|first defined here|
There is no way that I'm multiply defining test (although I don't know where the underscore is coming from) and it seems highly unlikely that the definition is somehow included twice. This is all the code there is.
I've ruled out that this error is due to some naming conflict with other functions or files being called test or test.c. Note that the multiple and the first definition are on the same line in the same file.
Does anyone know what is causing this and what I can do about it? Thanks!
You actually compile the source code of test.c twice:
The first time when compiling test.c itself,
The second time when compiling main.c which includes all the test.c source.
What you need in your main.c in order to use the test() function is a simple declaration, not its definition. This is achieved by including a test.h header file which contains something like:
void test(void);
This informs the compiler that such a function with input parameters and return type exists. What this function does ( everything inside { and } ) is left in your test.c file.
In main.c, replace #include "test.c" by #include "test.h".
A last point: with your programs being more complex, you will be faced to situations when header files may be included several times. To prevent this, header sources are sometimes enclosed by specific macro definitions, like:
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
void test(void);
#endif
The underscore is put there by the compiler and used by the linker. The basic path is:
main.c
test.h ---> [compiler] ---> main.o --+
|
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe
So, your main program should include the header file for the test module which should consist only of declarations, such as the function prototype:
void test(void);
This lets the compiler know that it exists when main.c is being compiled but the actual code is in test.c, then test.o.
It's the linking phase that joins together the two modules.
By including test.c into main.c, you're defining the test() function in main.o. Presumably, you're then linking main.o and test.o, both of which contain the function test().
You shouldn't include other source files (*.c) in .c files. I think you want to have a header (.h) file with the DECLARATION of test function, and have it's DEFINITION in a separate .c file.
The error is caused by multiple definitions of the test function (one in test.c and other in main.c)
I had similar problem and i solved it following way.
Solve as follows:
Function prototype declarations and global variable should be in test.h file and you can not initialize global variable in header file.
Function definition and use of global variable in test.c file
if you initialize global variables in header it will have following error
multiple definition of `_ test'|
obj\Debug\main.o:path\test.c|1|first defined here|
Just declarations of global variables in Header file no initialization should work.
Hope it helps
Cheers
Including the implementation file (test.c) causes it to be prepended to your main.c and complied there and then again separately. So, the function test has two definitions -- one in the object code of main.c and once in that of test.c, which gives you a ODR violation. You need to create a header file containing the declaration of test and include it in main.c:
/* test.h */
#ifndef TEST_H
#define TEST_H
void test(); /* declaration */
#endif /* TEST_H */
If you have added test.c to your Code::Blocks project, the definition will be seen twice - once via the #include and once by the linker. You need to:
remove the #include "test.c"
create a file test.h which contains the declaration:
void test();
include the file test.h in main.c
If you're using Visual Studio you could also do "#pragma once" at the top of the headerfile to achieve the same thing as the "#ifndef ..."-wrapping. Some other compilers probably support it as well ..
.. However, don't do this :D Stick with the #ifndef-wrapping to achieve cross-compiler compatibility. I just wanted to let you know that you could also do #pragma once, since you'll probably meet this statement quite a bit when reading other peoples code.
Good luck with it
Ages after this I found another problem that causes the same error and did not find the answer anywhere. I thought to put it here for reference to other people experiencing the same problem.
I defined a function in a header file and it kept throwing this error. (I know it is not the right way, but I thought I would quickly test it that way.)
The solution was to ONLY put a declaration in the header file and the definition in the cpp file.
The reason is that header files are not compiled, they only provide definitions.
How does one prevent an inclusion cycle in C? ie. You shouldn't have a.h #include "b.h", which #include's "c.h" which #include's "a.h". I'm looking for a way of preventing this from happening using some sort of C directive.
I had originally thought this would've prevented this from happening:
Contents of a.h:
#ifndef __A_H
#define __A_H
#include "b.h"
#endif // __A_H
Contents of b.h:
#ifndef __B_H
#define __B_H
#include "c.h"
#endif // __B_H
Contents of c.h:
#ifndef __C_H
#define __C_H
#include "a.h"
#endif // __C_H
But it doesn't seem to work.
It does work allright: the files are repeatedly included, but the sections protected by #ifdndef/#define/#endif are not repeated, and that breaks the cycle.
Use your compiler to produce the preprocessed output and look at it for yourself. With GNU CC, you need to use "-E" option on the .c[pp] file, like this:
gcc -E $(CFLAGS) -o foo.i foo.cpp
That should work. It's written correctly in your example and compiles fine for me. Did you mistype something in your actual code, or is it really some other problem you're seeing?
You shouldn't start things out with __, though, as that's reserved for the compiler and/or system libraries. Try some other names for your guards.
Macros with leading underscores are reserved for the preprocessor/compiler.
Try changing __*_H to something more standard.
I use HAVE__*_H.
ya in addition to the above things if you are working on turbo c and you are doing a project with these source files then do not attach the header files which are #included in the source files.And even then if it is not working then try it from command prompt because some compiler options give these errors again and again.so here if the header files contents are between the #ifndef and #endif then there will be no problem even you include both the files. So try removing the header files from the project keeping them in the same directory.bcos u didnt specified environment i specified turbo C because i faced this situation once on turbo C with the header files #included in source file and attached to the project files list then there will be "multiple declaration problem".also after compiling (even with errors) go to external command line and go to directory where that file is stored and try with the filename.exe directly.ok
This works.
Just to be sure, I actually compiled a test.c that included a.h with your 3 header files.
I verified this works for several versions of MSVC, Digital Mars and GCC.
I have a header file x.h which is included by more than one *.c source files.
This header file has some structure variables defined.
I have put multiple inclusion prevention guard at the beginning of the header file as:
#ifndef X_H
#define X_H
...
..
//header file declarations and definitons.
#endif//X_H
On building I get linker errors related to multiple definitions. I understand the problem.
Won't a multiple inclusion prevention guard at the top of header file as I have, prevent multiple inclusions of the header file x.h and thereby avoid multiple definitions of the variables that are there in x.h?
#pragma once does not work on this particular compiler, so what is the solution?
Someone had posted this answer to a similar question. It doesn't seem to work for me. How does this solution work?
If the linker is complaining, it means you have definitions rather than just declarations in your header. Here's an example of things that would be wrong.
#ifndef X_H
#define X_H
int myFunc()
{
return 42; // Wrong! definition in header.
}
int myVar; // Wrong! definition in header.
#endif
You should split this into source and header file like this:
Header:
#ifndef X_H
#define X_H
extern int myFunc();
extern int myVar;
#endif
C Source:
int myFunc()
{
return 42;
}
int myVar;
Header guards are only good for a single compilation unit, i.e., source file. If you happen to include a header file multiple times, perhaps because all headers included from main.c in turn include stdio.h then guards will help.
If you have the definition of a function f in x.h which is included by main.c and util.c, then it is like copying and pasting the definition of f into main.c when creating main.o and doing the same for util.c to create util.o. Then the linker will complain and this happens despite your header guards. Having multiple #include "x.h" statements in main.c is possible of course because of these guards.
Using include guards prevents one compilation unit from including the header twice. E.g. if header B.h includes A.h and B.cpp includes A.h and B.h, everything from A.h would be declared twice in the compilation B.cpp if you weren't using include guards.
Your include guards prevent this from happening, all's fine till now.
But you get multiple definitions at link time, i.e. two compilation units define the same thing, this probably means you got a real definition in your header, use extern for all variables, make sure functions are either inline or are defined in the cpp file.
If the functions aren't large, you can use "inline" before them and the linker won't complain.
Using a multiple inclusion guard prevents compiler errors, but you're getting a linker error. Do you have data definitions in the header file that don't use extern?
Maybe X_H is already defined somewhere else? I just ran into this issue, where Xlib defines X_H in /usr/include/X11/X.h.
To check, you can call gcc -dM -E (if you are using gcc), e.g. in the buildsystem I’m using that works with CC=gcc CFLAGS="-dM -E" make. If the output file contains #define X_H even though you remove it from your file (use Y_H for example), then it is already defined outside your source code.