0
votes

I have this C compilation issue.

It took me while to understand the root cause for the issue. Although, now that i have intercepted the issue, I am not sure I fully understated the full C compilation flow logic.

I have two directoriess: inc and src

In the inc directories I have one file: test.h In the src directories I have two file: test.c and main.c

The test.c file implements a function, let call it test(), and the main.c file call this test() function.

I declared this function in the test.h file

Now, I included this test.h file only in the main.c file, in order to let the main.c file to "see" the declaration of the test() function.

when compiling:

g++ -o test.o -c test.c
g++ -o main.o -c main.c
g++ -o test test.o main.o

In the last command I get an error of "undefined reference to 'test'

After debugging this issue, I found out that the missing include of the test.h file in the test.c file resolves the issue.

In other words, I need to includes the test.h file in both source files - main.c and test.c

My question is, why? Is it not enough to include the header file, test.h file, only in the main.c file, in order to let it "see" the function declaration, and in linkage phase the compiler would "know" to associate the test() function used in the main.c file to its implementation in the test.c file?

I thought that the declaration of the test() function in the test.h file makes it "extern" declaration, and therefore it will signal the compiler to find the function implementation in linkage phase

2
The preprocessor quite literally includes the contents of the included files at the place of the #include directive. That means only source file that includes a specific header file will know about the declarations in the header file. A source-file with all included header files are known as a translation unit and each translation unit is more or less stand-alone.Some programmer dude
Even if you don't get a compilation failure by not including test.h in test.c there will be no way for the compiler to check that the test() function prototype in test.h is correct: neither the compiler nor the linker will know if you are calling test() with incorrect arguments, or using an incorrect return value.Weather Vane
Without seeing the declaration and definition, it's hard to guess what's going wrong. It might be something to do with using a C++ compiler to compile what appears to be a C program. Why would you do that? And why is the question tagged with two languages?Mike Seymour
Please post the (relevant parts of the) files so that we can see the declarations and definitions.Angew is no longer proud of SO
This should compile and link just fine, as long as declaration of test function in test.h matches definiton in test.c.rubikonx9

2 Answers

1
votes

The issue is because your prototype doesn't match implementation.

If you would be using C compiler, your would get interesting run-time errors due to wrong parameter and return value handling, because the generated symbol typically doesn't include parameter information.

With C++ the compiler generates a method signature that depends on parameter types. So two functions with the same name but different arguments will produce two distinct symbols, so linker would not confuse them.

So fix your prototype and it would work...

0
votes

I don't think there should be any problem in just adding test.h in main.c and not in test.c. Please check your setup again.

You can either declare the function in test.h and include test.h in main.c

or declare the function as extern in main.c itself. In both ways linker has to do the job of finding definition of test()

Include files are usually to separate interfaces from implementations.