Here's my header file.
#ifndef P6_H
#define P6_H
#include <stdio.h>
void FoundationC();
void StructureC();
void PlumbingC();
void ElectricC();
void HVACC();
void SheatingC();
extern int DAYS;
#endif
I'm using a makefile to do all compilation. It's able compile the individual .o files file but when it tries turn those into a single executable it says that there multiple definitions of the variable DAYS even though that is extern and declared and initialized in each individually. I got this to work before but can't figure out why it's not working now.
Oh and here's my makefile code
all:
gcc -c P6.c
gcc -c foundations.c
gcc -c structure.c
gcc -c plumbing.c
gcc -c electric.c
gcc -c hvac.c
gcc -c sheating.c
gcc P6.h P6.o foundations.o structure.o plumbing.o electric.o hvac.o sheating.o -o P6
I realize P6.h probably doesn't have to be include in the command but the include guards should make it not matter no?
Also I'm sorry if this question is a dupe but I did previously look for answers and this issue is driving me crazy on a personal level despite the fact that's it's for school.
Here are the errors I get.
gcc -c P6.c
gcc -c foundations.c
gcc -c structure.c
gcc -c plumbing.c
gcc -c electric.c
gcc -c hvac.c
gcc -c sheating.c
gcc P6.h P6.o foundations.o structure.o plumbing.o electric.o hvac.o sheating.o -o P6
structure.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
plumbing.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
electric.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
hvac.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
sheating.o:(.data+0x0): multiple definition of `DAYS'
foundations.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
To help you understand, the following is an extension of #FUZxxl's answer, which is correct. If you have the following in your compilation unit (a compilation unit is the .c source file plus all included .h files):
extern int DAYS;
...
int DAYS = 1;
then the second declaration of DAYS overrides the first declaration which stated it is an extern. So, the variable is now no longer an extern and if you do this in more than one source file you now consequently have multiple definitions and the linker complains.
If you must initialize DAYS, then you can do that in one place, preferably in the main file.
initialized in each individually.
There's your mistake. What do you think is supposed to happen if you initialize the same variable in different translation units? What do you think happens if these use different values?
You can only define a variable once in your program, multiple declarations are fine though. From all but one translation unit, remove the definition of DAYS to fix this problem.
First of all,remove P6.h from the last command in the makefile.-o option in gcc is used for compiling and linking multiple source files.So,this doesn't make any sense.
Secondly define DAYS as "int DAYS" in a .c file,you could declare it as extern in the corresponding .h file and include this .h file in all other source .c files.This will resolve this issue of multiple definitions.
Example:Define days as "int DAYS" in A.c and you declare it as "extern int DAYS" in A.h.Now,you could include this A.h in rest other source files like B.c , C.c ,D.c and so on.
Related
I've just completed a school assignment and I'm having a problem testing my code because I keep getting the following output after running make packetize (it's a makefile the professor gave us)
cc packetize.c -o packetize
/tmp/ccJJyqF6.o: In function `block_to_packet':
packetize.c:(.text+0xb1): undefined reference to `crc_message'
collect2: ld returned 1 exit status
make: *** [packetize] Error 1
block_to_packet is defined in a file called packetize.c, crc_message is defined in crc16.c (both of which contain an #include "data.h" line). data.h also has the function heading for crc_message in it All of these files are in the same directory. I've been trying to compile them for the past hour and a half and have searched Google endlessly with no avail. It has something to do with linking I've read, my instructor has not taught this and so I don't know how to compile these files to test their outputs. Can anyone let me know what's wrong?
Your header files are absolutely OK. What you have there is a linker error: The compilation of packetize.c ran without problems, but then you're trying to link an executable file packetize (since you did not give the -c option which states "compile to object file"). And the executable would need the compiled code from crc16.c as well.
Either you have to give all sources on the compiler line:
cc packetize.c crc16.c -o myApp
Or you have to compile into individual object files, eventually linked together:
cc -c packetize.c -o packetize.o
cc -c crc16.c -o crc16.o
cc packetize.o crc16.o -o myApp
The former is what you'd do in a one-shot command line, the latter is what a Makefile usually does. (Because you do not need to recompile crc16.c if all you did was modify packetize.c. In large projects, recompiles can take significant amounts of time.)
Edit:
Tutorial time. Take note of the existence / absence of -c options in the command lines given.
Consider:
// foo.c
int foo()
{
return 42;
}
A source file defining the function foo().
// foo.h
int foo();
A header file declaring the function foo().
// main.c
#include "foo.h"
int main()
{
return foo();
}
A source file referencing foo().
In the file main.c, the include makes the compiler aware that, eventually, somewhere, there will be a definition of the function foo() declared in foo.h. All the compiler needs to know at this point is that the function will exist, that it takes no arguments, and that it returns int. That is enough to compile the source to object code:
cc -c main.c -o main.o
However, it is not enough to actually compile an executable:
cc main.c -o testproc # fail of compile-source-to-exe
ld main.o -o testproc # fail of link-object-to-exe
The compiler was promised (by the declaration) that a definition of foo() will exist, and that was enough for the compiler.
The linker however (implicitly run by cc in the first example) needs that definition. The executable needs to execute the function foo(), but it is nowhere to be found in main.c. The reference to foo() cannot be resolved. "Unresolved reference error".
You need to either compile both source files in one go...
cc foo.c main.c -o testproc # compile-source-to-exe
...or compile foo.c as well and provide the linker with both object files so it can resolve all references:
cc -c foo.c -o foo.o
ld foo.o main.o -o testproc # link-objects-to-exe
Post Scriptum: Calling ld directly as pictured above most likely will not work just like that. Linking needs a couple of additional parameters, which cc adds implicitly -- the C runtime support, the standard C library, stuff like that. I did not give those parameters in the examples above as they would confuse the matter and are beyond the scope of the question.
You have to compile crc16.c as well and link these two object files to build the binary. Otherwise packetize.c, from where crc_message() is being called, has no knowledge of it.
Try using
cc packetize.c crc16.c -o packetize
Your call crc_message() from packetize.c would just be fine.
As Totland writes crc_message is defined in crc16.c; which means that packetize.c can't see the definition, no matter how many shared headers they have. You do not have a compile error but an error from the linker.
If you compile your c files first to object files and then link everything to an executable it will work.
I have a number of .c files, i.e. the implementation files say
main.c
A.c
B.c
Where functions from any of the files can call any function from a different files. My question being, do I need a .h i.e. header file for each of A and B's implementation where each header file has the definition of ALL the functions in A or B.
Also, main.c will have both A.h and B.h #included in it?
If someone can finally make it clear, also, how do I later compile and run the multiple files in the terminal.
Thanks.
Header contents
The header A.h for A.c should only contain the information that is necessary for external code that uses the facilities defined in A.c. It should not declare static functions; it should not declare static variables; it should not declare internal types (types used only in A.c). It should ensure that a file can use just #include "A.h" and then make full use of the facilities published by A.c. It should be self-contained, idempotent (so you can include it twice without any compilation errors) and minimal. You can simply check that the header is self-contained by writing #include "A.h" as the first #include line in A.c; you can check that it is idempotent by including it twice (but that's better done as a separate test). If it doesn't compile, it is not self-contained. Similarly for B.h and B.c.
For more information on headers and standards, see 'Should I use #include in headers?', which references a NASA coding standard, and 'Linking against a static library', which includes a script chkhdr that I use for testing self-containment and idempotency.
Linking
Note that main.o depends on main.c, A.h and B.h, but main.c itself does not depend on the headers.
When it comes to compilation, you can use:
gcc -o program main.c A.c B.c
If you need other options, add them (most flags at the start; libraries at the end, after the source code). You can also compile each file to object code separately and then link the object files together:
gcc -c main.c
gcc -c A.c
gcc -c B.c
gcc -o program main.o A.o B.o
You must provide an header file just if what is declared in a .c file is required in another .c file.
Generally speaking you can have a header file for every source file in which you export all the functions declared or extern symbols.
In practice you won't alway need to export every function or every variable, just the one that are required by another source file, and you will need to include it just in the required file (and in the source paired with the specific header file).
When trying to understand how it works just think about the fact that every source file is compiled on its own, so if it's going to use something that is not declared directly in its source file, then it must be declared through an header file. In this way the compiler can know that everything exists and it is correctly typed.
It would depend on the compiler, but assuming you are using gcc, you could use something like this:
gcc -Wall main.c A.c B.c -o myoutput
Look at http://www.network-theory.co.uk/docs/gccintro/gccintro_11.html (first google answer) for more details. You could compile it into multiple object files/ libraries:
gcc -c main.c
gcc -c A.c
gcc -c B.c
gcc -o mybin main.o A.o B.o
You want to use
gcc -g *.c -lm
It saves typing and will allow you to link all your c files in your project.
dir1 has dir2, file1.c and file1.h.
dir2 has file2.c
Now, if I want to access a function defined in file1.c in file2.c, I need to declare it in file1.h and include file1.h in file2.c -- is that a valid assumption?
If no, please explain.
If yes, even after doing that I am getting "undefined reference to function" error.
file2.c:29: undefined reference to `function'
collect2: ld returned 1 exit status
* Error code 1
Compiling a c program happens in two steps basic steps: compiling and linking. Compiling turns source code into object code, and linking puts object code together, and ties all of the symbols together.
Your problem is a linker problem, not a compiler problem.
You are likely running the following:
gcc dir_2/file2.c
instead, do the following:
gcc -c dir_2/file2.c
gcc -c file1.c
gcc -o out file1.o file2.o
The reason this happens isn't because you didn't declare the function in the header, or didn't include the header properly. When the linker tries to put all the symbols together in the executable, it can't find your function because you are only linking half of your program.
including the .h files is not enough because it only includes the prototype of that function not the definition of the function and the definition of the function is in a seperate .c file.
one way to fix it is just type:
gcc -o out file1.c file2.c
or as Nate says you could seperate the compilation process and the link process
Now, if I want to access a function defined (in) file1.c in file2.c
A function defined in FILE1.c
Access from FILE2.c
example function: void sync(all){start sync ...}
Need on File2.h
include File1.h
AND Need on File2.c
include File1.h
Nothing else!
I always use also the keyword EXTERN in File2.h
Example:
extern void sync(all);
The voted also work, choose with what you feel better, I feel better when I saw
what happend during coding.
Imagine an other team member has to review your code, it will be harder...
/me/home/file1.c containes function definition:
int mine(int i)
{
/* some stupidity by me */
}
I've declared this function in
/me/home/file1.h
int mine(int);
if I want to use this function mine() in /me/home/at/file2.c
To do so, all I need to do is:
file2.c
#include "../file1.h"
Is that enough? Probably not.
After doing this much, when I compile file2.c, I get undefined reference to 'mine'
You will also need to link the object file from file1. Example:
gcc -c file2.c
gcc -c ../file1.c
gcc -o program file2.o file1.o
Or you can also feed all files simultaneously and let GCC do the work (not suggested beyond a handful of files);
gcc -o program file1.c file2.c
Don't use ../ in a header. Instead, instruct gcc to use the parent directory as include path:
(in the at directory):
gcc -I../ -c file2.c
After doing this much, when I compile file2.c, I get undefined reference to 'mine'
No, you don't. It's not compiling that causes those errors. It's this other thing, called "linking".
The compiler compiles one "translation unit" - the result of running the preprocessor on one source file, possibly pulling in more stuff via #include - at a time, and then the linker sticks these together to make an executable. Typically the same program serves as both the compiler and linker, with different flags, and typically you can tell it to do everything at once (and not save any temporary files for the compiled translation units). But you do need to tell it what to link, and you do need to compile everything that will be linked.
This is a question from job interview.Let's say we have "a.c" source file with some function and "a.h" as its header file.Also we have main.c file which calls that function.Now let's suppose we have "a.h" and "a.o"(object file) and a.c is unavailable.How do we call this function now?
(I had a hint that we need to use function pointers.Another hint is to do this using pre-compiler directives such as #define and #ifndef).
Also i would like to know how in .h file we know if we are linked properly to source file?
Thank You
Just include a.h from main.c and you can use the functions declared in a.h. Then just compile it with the same compiler version as a.o is build:
gcc -c main.c
gcc main.o a.o
To compile main.c, you need the function definition. You already have that in a.h. So you would write:
// main.c
#include "a.h"
int main()
{
foobar(); // Let's say this is the function from a.h
}
When compiling it, you would have to include the object file at the linking stage. So using gcc...
gcc -c main.c // Compile main.c to main.o
gcc -o main main.o a.o
No function pointers or macros needed.
The way you describe it, you only need a header file to call the function. The header file contains the prototype of the function, which allows the compiler to know what the signature of the function is.
You would then link in your object file (which contains the compiled version of function) and everything would be OK.
I don't know why you would need functions pointers or pre-compiler directives. Maybe you didn't understand the question 100%?
In main.c, call the function as normal.
Then compile main.c to main.o. gcc -c main.c
Then link a.o and main.o. gcc main.o a.o
Something about this question sounds garbled. How you write the function call in main depends solely on its declaration in a.h. The presence or absence of a.c doesn't change that. Certainly nothing involving macros or function pointers.
Compiling and linking are two distinct steps; the compiler checks that you're passing the right number and types of arguments and assigning the result to the right type of object based on the function's declaration, while the linker attempts to resolve the reference to the function's implementation in the machine code.
The result of compiling and linking is a binary sludge that may or may not have any obvious relationship to the original source code1. Debug versions preserve varying levels of information to support source-level debuggers, but you can pretty much rely on release versions not preserving any useful source information.
1. Every now and again someone asks for a tool to recover source code from an executable; this is often described as attempting to turn hamburger back into cows.