I'm writing a simple application in ANSI C. I am using GCC in a Unix environment.
I have the following sample application:
//main.c
#include "foo.h"
int main()
{
int result;
result = add(1,5);
return0;
}
Header:
//foo.h
#ifndef FOO_H_INCLUDED
#define FF_H_INCLUDED
int add(int a, int b);
#endif
Implementation:
//foo.c
int add(int a, int b)
{
return a+b;
}
I am compiling my program with the following command:
cc main.c -o main.o
The compiler complains that 'reference to add is undefined'. Is this a linking problem? How do properly make use of my header?
Thanks!
You need to compile both your source files together:
cc main.c foo.c -o main
Also, in this case, -o produces an executable, so calling it main.o can be misleading.
Yet another tidbit, though unrelated to the question: the #ifndef and #define in foo.h don't match.
The header is not your current problem. Your current problem is that you're not compiling the add function definition in foo.c.
Try
cc main.c foo.c -o main.o
If you are trying to compile main.c into an assembled object file, you need to prevent gcc from trying to link. This is done via
cc -c main.c -o main.o
You can compile all other object files, then when you have all of your object files ready, you simply do
cc main.o obj1.o anotherOBJ.o -o myExecutableBinary
"undefined reference" is a linker error, not a compiler error.
The compiler sees the declaration in the header, but you have not compiled or linked the definition in foo.c. Your title uses the term definition incorrectly.
Related
I have 3 files in this program, lab4.c, functions.h, functions.c
The lab4.c calls a function multiply(), whose prototype is in functions.h and is defined in functions.c. Multiply then used multiple other functions from functions.c. The only includes I have for this is in lab4.c including functions.h, do I need more? The problem I am having is described below
lab4:
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
int main(void) {
...
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
functions.c:
void divideByPowerOf2(unsigned int* a, int power){
*a >>= power;
}
void multiplyByPowerOf2(unsigned int* a, int power){
*a <<= power;
}
...
Currently, my makefile looks like this:
Makefile:
#Makefile
all: lab4
lab4: lab4.o functions.o functions.h
gcc -Wall -o lab4 lab4.o functions.o
lab4.0: lab4.c
gcc -c lab4.c
functions.o: functions.c
gcc -c functions.c
now this will recompile when I change the header file, but the changes dont actually take effect. For example, if I change the header file to
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
//void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
the program still works just fine. Im assuming I may have messed up linking the files with includes and everything, as that usually confuses me. For example, does functions.c need to refer to anything? and does functions.h need any kind of reference to the .c files? How do I get this to work properly so that if I change the header file, it recompiles and actually uses the new header
Thanks for any help!
First, there's a typo here:
lab4.0: lab4.c
should be
lab4.o: lab4.c
then, your function.h should be on the source => object dependency lines, not on the object => executable line, else, if you change the .h file, it just re-links without rebuilding the .o files: it changes nothing.
Moreover, it's good to use -Wall, but you have to use it when you compile your files, not when you link the executable, or you'll miss the actual compilation warnings (-Wall during the link phase only is pretty useless).
For instance, the -Wall flag would show you that commenting a prototype generates an "implicit declaration" warning (which can lead to an improper call/return values of a function). It's even more effective with -Werror, which turns warnings into errors, so you cannot ignore warnings.
Here's how your makefile should look like:
all: lab4
CFLAGS = -Wall
lab4: lab4.o functions.o
gcc -o lab4 lab4.o functions.o
lab4.o: lab4.c functions.h
gcc $(CFLAGS) -c lab4.c
functions.o: functions.c functions.h
gcc $(CFLAGS) -c functions.c
note that if you only have 2 source files and they're small enough, you could even not use the make file by just running:
gcc -Wall -o lab4 lab4.c functions.c
in a script. That's not adapted if you have too many / big source files, because it rebuilds everything everytime.
I am having trouble with multiple definitions of functions. All other solutions here on stack overflow have not worked out for me.
This is my main.c:
#include "lib.h"
int main(){
test();
}
This is the lib.c file:
#include "lib.h"
int var;
void test(){
//code here
}
And this is the lib.h file:
#ifndef _HTTPLIB_H_
#define _HTTPLIB_H_
#include <stdio.h>
extern int var;
extern void test();
#endif
I have checked and there are no definitions of any function twice and I am never including a .c source file.
I am compiling with
gcc lib.c main.c -Wall -g -o main
main: In function 'test': (.text+0xfdd): multiple definition of 'test' /tmp/ccb8byZi.o:lib.c:(.text+0xef9): first defined here'
real code:
main file: http://pastebin.com/xr3DF0TE
lib.c and lib.h file: http://pastebin.com/KemhKX3f
This is the compilation code
gcc -lpthread -D_REENTRANT httplib.c http.c -o -g http
real error message:
http: In function `sigusr1':(.text+0xfdd): multiple definition of `sigusr1'/tmp/ccb8byZi.o:httplib.c:(.text+0xef9): first defined here
gcc -lpthread -D_REENTRANT httplib.c http.c -o -g http
Here's your problem: You're telling gcc to compile 3 files (httplib.c, http.c, http) into an executable called -g. This is because the argument after -o is taken to be the output filename.
The errors are caused by you apparently having an http executable lying around, which already contains the (compiled) functions defined in httplib.c.
Fix:
gcc -lpthread -D_REENTRANT httplib.c http.c -g -o http
I am having a hard time compiling a simple cuda program consiting of only two files.
The main.c looks like this:
#include "my_cuda.h"
int main(int argc, char** argv){
dummy_gpu();
}
The cuda.h looks like this:
#ifndef MY_DUMMY
#define MY_DUMMY
void dummy_gpu();
#endif
And the my_cuda.cu file loos like this:
#include <cuda_runtime.h>
#include "my_cuda.h"
__global__ void dummy_gpu_kernel(){
//do something
}
void dummy_gpu(){
dummy_gpu_kernel<<<128,128>>>();
}
However if I compile I allways receive the following error:
gcc -I/usr/local/cuda/5.0.35/include/ -c main.c
nvcc -c my_cuda.cu
gcc -L/usr/local_rwth/sw/cuda/5.0.35/lib64 -lcuda -lcudart -o md.exe main.o my_cuda.o
main.o: In function `main':
main.c:(.text+0x15): undefined reference to `dummy_gpu'
collect2: ld returned 1 exit status
Thank you for your help.
You have a problem with symbol name mangling. nvcc uses the host C++ compiler to compile host code, and this implies that symbol name mangling is applied to code emitted by the CUDA toolchain.
There are two solutions to this problem. The first is to define dummy_gpu using C linkage, so change your my_cuda.cu to something like this:
extern "C" {
#include "my_cuda.h"
}
.....
extern "C"
void dummy_gpu(){
dummy_gpu_kernel<<<128,128>>>();
}
Note that you will need to change your linkage command to this:
gcc -L/usr/local_rwth/sw/cuda/5.0.35/lib64 -o md.exe main.o my_cuda.o -lcuda -lcudart
because the CUDA shared libraries need to be specified after the object files that use them.
Your second alternative would be to use either g++ or nvcc to do the linking, in which case the whole problem should disappear.
You have a C/C++ linkage problem. nvcc is decorating things in a C++ fashion but your gcc compiler is handling things using C style linkage. A simple way to fix it is to rename your main.c to main.cpp and then repeat your commands using g++ instead of gcc
Every time I compile I get the following error message:
Undefined reference to ( function name )
Let's say I have three files: Main.c, printhello.h, printhello.c. Main.c calls function print_hello(), which returns "Hello World". The function is defined in printhello.c.
Now, here's the following code of printhello.h:
#ifndef PRINTHELLO_H
#define PRINTHELLO_H
void print_hello();
#endif
I am sure this code is fine. I still don't know why is it giving me the error, though. Can you help me?
Undefined references are the linker errors. Are you compiling and linking all the source files ? Since the main.c calls print_hello(), linker should see the definition of it.
gcc Main.c printhello.c -o a.out
The error is, I think, a linker error rather than a compiler error; it is trying to tell you that you've not provided all the functions that are needed to make a complete program.
You need to compile the program like this:
gcc -o printhello Main.c printhello.c
This assumes that your file Main.c is something like:
#include "printhello.h"
int main(void)
{
print_hello();
return 0;
}
and that your file printhello.c is something like:
#include "printhello.h"
#include <stdio.h>
void print_hello(void)
{
puts("Hello World");
}
Your declaration in printhello.h should be:
void print_hello(void);
This explicitly says that the function takes no parameters. The declaration with the empty brackets means "there is a function print_hello() which returns no value and takes an indeterminate (but not variadic) list of arguments", which is quite different. In particular, you could call print_hello() with any number of arguments and the compiler could not reject the program.
Note that C++ treats the empty argument list the same as void print_hello(void); (so it would ensure that calls to print_hello() include no arguments), but C++ is not the same as C.
Another way to do it is to explicitly build object files for the printhello:
gcc -c printhello.c -o printhello.o
gcc -o Main main.c printhello.o
This has the added benefit of allowing other programs to use the print_hello method
It seems that the error is from the linker and not the compiler. You need to compile and link both the source files. I think what you are doing is simply including the header file in Main.c and you are not compiling the printhello.c
You need to :
gcc Main.c printhello.c -o myprog
or
construct the object files first
gcc -c printhello.c
gcc -c Main.c
then link them
gcc Main.o printhello.o
How can I include foo() function of foo.c in this small program (sorry for my noob question):
In my foo.h file:
/* foo.h */
#include <stdio.h>
#include <stdlib.h>
int foo(double largeur);
In foo.c:
/* foo.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int foo(double largeur)
{
printf("foo");
return 0;
}
And in main.c:
/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int main(int argc, char *argv[])
{
printf("Avant...");
foo(2);
printf("Apres...");
return 0;
}
After compiling:
$ gcc -Wall -o main main.c
I get this error:
Undefined symbols: "_foo",
referenced from:
_main in ccerSyBF.o ld: symbol(s) not found collect2: ld
returned 1 exit status
Thanks for any help.
$ gcc -Wall -o main main.c foo.c
GCC doesn't know to look for foo.c if you don't tell it to :)
Creating a program in C requires two steps, compiling and linking. To just run the compiling part, use the -c option to gcc:
gcc -c main.c
This creates an object file, main.o (or main.obj on Windows). Similarly for gcc -c foo.c. You won't get the error message above at this stage. Then you link these two object files together. At this stage, the symbol foo is resolved. The reason you got the error message was because the linker couldn't find the symbol, because it was only looking at main.o and not foo.o. The linker is usually run from gcc, so to link your object files and create the final executable file main, use
gcc -o main main.o foo.o
You have to compile foo.c also because it is another module. Let me see how they do it in gcc:
$ gcc -Wall main.c foo.c -o main
You could also do this in your MakeFiles, like this:
APP_NAME = Foo
Foo_HEADERS = foo.h
Foo_FILES = main.c foo.c
If you're not so much familiar with MakeFiles i suggest you to take a look at Make Docs, but this is a simple example, APP_NAME sets the name of the compiled executable(in this case is Foo), Foo_HEADERS will set the headers used by your application, Foo_FILES you will set the source files of your applications, remember to put the APP_NAME(in this case Foo) at the beginning of _HEADERS and _FILES. I suggest you to use MakeFiles because they will organize you application build process and will be better for the end-user.