undefined reference when including a header file - c

I get an error when I include a header file, but not if I include the source file instead.
The function is defined in the source file like this:
/* in User.c */
struct User {
const char* name;
};
struct User* addedUser(const char* name) {
struct User* user = malloc(sizeof(struct User));
user->name = name;
return user;
}
And used like this:
/* in main.c */
int test_addedUser() {
char* newName = "Fooface";
struct User* newUser = addedUser(newName);
assert(!strcmp(newName, newUser->name));
return 0;
}
This works great. I am able to call test_addUser without a problem when I #include "User.c".
However, I would like to #include "User.h" instead, which is located in the same directory:
/* in User.h */
struct User {
const char* name;
};
struct User* addedUser(const char*);
But, if I #include "User.h" instead of User.c, I get an error:
CMakeFiles/run_tests.dir/src/tests.c.o: In function `test_addedUser':
/home/rid/port/src/tests.c:(.text+0x4eb): undefined reference to `addedUser'
It seems strange to me that the reference works just fine when including the source file User.c but it is unable to reconcile User.h.
Any ideas why this might be?

#include means that the file included is copied into the source file.
So when you include your .c file, the function's code is here and it works.
If you include only the header file, it's good thanks to that your functions will know each other, at least they will now they exist but they need their code to work together, so you need now to compile your two files.c together, not one by one.
Maybe you're compiling by yourself :
gcc file1.c file2.c
Or with an IDE, you have to adjust the compiling options.
If you want to compile the C files separatly, you have to compile them in object files (-c option with gcc), then link them.

So I created some custom lib folder for example "engine" and placed some .cpp files in it:
main.cpp
engine/sprite.cpp
engine/sprite.h
engine/unit.cpp
engine/unit.h
So before compile cmd looked like:
g++ -o main main.cpp
After adding folder:
g++ -Iengine -o main main.cpp engine/*cpp
And it works

Related

How to fix my error while compiling my C file? [duplicate]

I'm working on a simple class List, but when compiling the header and cpp file, I get the error: undefined reference to `main'
What am I doing wrong, and how could I fix this?
Here is the list.h file that has simple headers:
list.h
#ifndef LIST_H
#define LIST_H
#include <string>
const int DEFAULT_CAPACITY = 100;
class List
{
public:
List();
List(int capacity);
~List();
void push_back(std::string s);
int size() const;
std::string at(int index) const;
private:
std::string* mData;
int mSize;
int mCapacity;
};
#endif
And here is the list.cpp file:
list.cpp
#include "list.h"
#include <string>
List::List(){
mData = new std::string[DEFAULT_CAPACITY];
mSize = 0;
mCapacity = 100;
};
List::List(int capacity){
mData = new std::string[capacity];
mSize = 0;
mCapacity = capacity;
};
List::~List(){
delete[] mData;
};
void List::push_back(std::string s){
if (mSize<mCapacity){
mData[mSize] = s;
mSize++;
}
};
int List::size() const{
return mSize;
};
std::string List::at(int index) const{
return mData[index];
};
I tried experimenting around with "using namespace std" and how to include , but I can't figure out how to get these errors to go away. What is causing them?
You should be able to compile list.cpp, you can't link it unless you have a main program. (That might be a slight oversimplification.)
The way to compile a source file without linking it depends on what compiler you're using. If you're using g++, the command would be:
g++ -c list.cpp
That will generate an object file containing the machine code for your class. Depending on your compiler and OS, it might be called list.o or list.obj.
If you instead try:
g++ list.cpp
it will assume that you've defined a main function and try to generate an executable, resulting in the error you've seen (because you haven't defined a main function).
At some point, of course, you'll need a program that uses your class. To do that, you'll need another .cpp source file that has a #include "list.h" and a main() function. You can compile that source file and link the resulting object together with the object generated from list.cpp to generate a working executable. With g++, you can do that in one step, for example:
g++ list.cpp main.cpp -o main
You have to have a main function somewhere. It doesn't necessarily have to be in list.cpp. And as a matter of style and code organization, it probably shouldn't be in list.cpp; you might want to be able to use that class from more than one main program.
Undefined reference to main() means that your program lacks a main() function, which is mandatory for all C++ programs. Add this somewhere:
int main()
{
return 0;
}

Call external function written in C from another file written in C in a Linux enviroment

I am having trouble calling an external function I wrote in the Pico editor in linux. The program should call an external function and they are both written in C.
#include????
void calcTax()
float calcfed()
float calcssi()
// stub program
#include"FILE2"???or do I use"./FILE2"// not sure which to use here or what extension the file should have. .c or .h and if it is .h do I simply change the file name to file.h?
#include<stdio.h>
#define ADDR(var) &var
extern void calctaxes()
int main()
{
}
I am using gcc to compile but it will not compile. both files are in the same directory and have the .c extension
I am a new student so bear with me.
Normally, when you want a function in one compilation unit to call a function in another compilation unit, you should create a header file containing the function prototypes. The header file can be included in both compilation units to make sure that both sides agree on the interface.
calctax.h
#ifndef calctax_h_included
#define calctax_h_included
void calctaxes(void);
/* any other related prototypes we want to include in this header */
#endif
Note that extern is not required on functions, only global data. Also, since the function takes no arguments, you should put void in the argument list, and you also need a semi-colon at the end of the prototype.
Next, we can include this header file in the .c file that implements the function:
calctax.c
#include "calctax.h"
void calctaxes(void)
{
/* implementation */
}
Finally, we include the same header file in our main .c file that calls the function:
main.c
#include "calctax.h"
int main(int argc, char **argc)
{
calctax();
return 0;
}
You can compile and link these together with
% gcc -o main main.c calctax.c
Normally you don't want to include .c implementation files. The normal thing to do is have two source files that you build into objects:
cc -o file1.o file1.c
cc -o file2.o file2.c
And then link them into an executable at the end:
cc -o example file1.o file2.o
To allow calling functions between the two .c files, you create a header (.h) file that has function declarations for everything you're interested in sharing. For you, that might be something like header.h, containing:
void calcTax(void);
float calcfed(void);
float calcssi(void);
Then, just #include "header.h" from the implementation files where you need to know about those functions.

Get the included path in same program

Suppose I have a program
main.c
#include "file.h"
#include <stdio.h>
int main()
{
//Code to found the included path
}
gcc -I /local main.c
How can I found the included path of header file inside this program
Now their can be 3 included path
current directory
ENV set in the Path VARIABLE or other
Directory included with -I option
Please provide a way to get this inside the same program.
For the include files that you could edit you can use the __FILE__ macro. It makes the preprocessor insert the full file's name like /the/directory/filename.
Just add the follow line to you header:
static const char MyIncludeFileName[] = __FILE__;
If you do not refer to MyIncludeFileName (from the code which includes the header) the compiler might issue a warning that MyIncludeFileName is declared but not used. To tell the compiler be quiet about this do the followings:
static const char MyIncludeFileName[] __attribute__ ((unused)) = __FILE__;

Including a typedef in two header files

I have this in ball.h:
#ifndef BALL_H_
#define BALL_H_
...
typedef void *PBALL ;
...
#endif
in paddle.h I have:
#ifndef PADDLE_H_
#define PADDLE_H_
...
int contact_made(struct pppaddle*, PBALL);
...
#endif
I get an error in paddle.h because it doesn't know about PBALL. So if I add:
#ifndef BALL_H_
#include "ball.h"
#endif
to paddle.h (with or without the if statement) it works in my Cygwin environment. But in Linux when I go to compile I get: "multiple definition of `newPBALL'" error on the source file that uses PBALL and also on the functions defined in ball.h. How can I get paddle.h to understand PBALL without running into these problems in Linux?
My ball.c file:
struct newball {
int x_pos, x_dir, y_pos, y_dir, y_delay, y_count, x_delay, x_count;
char symbol;
};
typedef struct newball *ball_struct_ptr;
struct newball the_ball;
#include "ball.h"
PBALL newPBALL() {
the_ball.y_pos = Y_INIT;
the_ball.x_pos = X_INIT;
the_ball.y_count = the_ball.y_delay = Y_DELAY;
the_ball.x_count = the_ball.x_delay = X_DELAY;
the_ball.y_dir = 1;
the_ball.x_dir = 1;
the_ball.symbol = DFL_SYMBOL; //Set the symbol of the ball
PBALL ptr = &the_ball;
return ptr;
}
Well instead of trying to import one header file into another (which worked in Cygwin but not Linux) or not importing the header into the other header (which worked for Linux but not Cygwin) I did this in both header files:
#ifndef TYPEDEF_PBALL_DECLARED_
#define TYPEDEF_PBALL_DECLARED_
typedef void *PBALL ;
#endif
Now it's working in both environments. I'll leave this open for a little while in case there is a better solution than having to declare typedef twice in two header files.
I don't know what precisely is the problem, but I might be able to tell you how to figure it out.
Build your program as usual. Capture the command line of the failing compilation step. This might be something like:
gcc -c -o foo/bar.o baz.c
So baz.c presumably #includes the "bad" header files. And you get the compilation error. Now, track it down by just preprocessing your sources:
gcc -E -o foo/bar.c baz.c
-E being the option to stop after preprocessing, before actual compilation. Now try to compile the preprocessed file:
gcc -c -o foo/bar.o bar.c
You should find a similar error as before. Now look at the preprocessed source in bar.c from step 2 and you might easier find the cause. Start with just searching for the identifier that the compiler is complaining about--is it in fact declared multiple times? If so, why? Could it be in another header? Or perhaps there is a #define somewhere that is messing with your names?

Duplicate Symbol in C

I have two source files:
Source FIle 1 (assembler.c):
#include "parser.c"
int main() {
parse_file("test.txt");
return 0;
}
Source File 2 (parser.c):
void parse_file(char *config_file);
void parse_file(char *src_file) {
// Function here
}
For some reason, when compiling it is giving me the following error:
duplicate symbol _parse_file in ./parser.o and ./assembler.o for architecture x86_64
Why is it giving me a duplicate symbol for parse_file? I am just calling the function here... No?
First off, including source files is a bad practice in C programming. Normally, the current translation unit should consist of one source file and a number of included header files.
What happens in your case is that you have two copies of the parse_file function, one in each translation unit. When parser.c is compiled to an object file, it has its own parse_file function, and assembler.c also has its own.
It is the linker that complains (not the compiler) when given two object files as an input, each of which contains its own definition of parse_file.
You should restructure your project like this:
parser.h
void parse_file(char *);
parser.c
void parse_file(char *src_file) {
// Function here
}
assembler.c
/* note that the header file is included here */
#include "parser.h"
int main (void) {
parse_file("test.txt");
return 0;
}
You're including the parser.c file, which means all the code that is in that file will be "copied" to assembler.c file. That means that the entire contents of parser.c will be compiled when the compiler is compiling parser.c, and then it'll be compiled again when the compiler is compiling assembler.c
That's what headers are for.
In the header you can put only the declarations, so you can include it without creating the same symbols again in a different translation unit.
so you can just create a parser.h containing just the declaration of the function:
void parse_file(char *config_file);
then in your assembler.c you include just the header:
#include "parser.h" //include the header, not the implementation
int main() {
parse_file("test.txt");
return 0;
}
You are including the .c file which contains the definition of the function parse_file. Thus it is defined twice, once in each translation unit, which is not allowed.
As other answers state, including the source means the file will be copied to parser.c and will be defined there as well in the original place (assembler.c). To solve this, either create a header file with your prototype:
parser.h
void parse_file(char *config_file);
And include that file:
assembler.c
#include "parser.h"
int main() {
parse_file("test.txt");
return 0;
}
Or remove the include and provide a clue to the function:
int main() {
void parse_file(char *);
parse_file("test.txt");
return 0;
}
Or even simply remove the include at al. Not good practice, as the compiler (without information on a function) will consider its returned value is an integer and may cause other warnings.

Resources