C compiling - 'undefined reference to function' when trying to link object files - c

so i create the object files with
cc -c MAIN.C
cc -c tablero.c
but then when i try to link them to an executable with
cc MAIN.o tablero.o
i get
undefined reference to `asdf()'
(function defined in tablero.c and called in MAIN.C)
here are my files:
i have MAIN.C
#include <stdio.h>
#include <cstring>
#include "tablero.h"
int main()
{
int c;
printf( "Enter a value :");
c = getchar( );
putchar(c);
printf( "\nYou entered: ");
c = asdf ();
putchar(c);
return 0;
}
i have tablero.h
#ifndef TABLERO_H_
#define TABLERO_H_
int asdf();
#endif // TABLERO_H_
and i have tablero.c
#include "tablero.h"
int asdf() {return 48;}; //48 is 0 in ascii

You have been bitten by an obscure feature of the cc tool on many Unixy systems: files whose suffix is lowercase .c are compiled as C, but files whose suffix is uppercase .C are compiled as C++! Therefore, your main (compiled as C++) contains an external reference to a mangled function name, asdf() (aka _Z4asdfv), but tablero.o (compiled as C) defines only an unmangled name, asdf.
This is also why you were able to include the C++ header file <cstring> in what was meant to be a C program.
Rename MAIN.C to main.c (and change <cstring> to <string.h>), recompile main.o, and your program should link.
If you actually want to compile part of your program as C and part as C++, then you can annotate your header files with extern "C" to make the symbols match up:
#ifndef TABLERO_H_
#define TABLERO_H_
#ifdef __cplusplus
extern "C" {
#endif
int asdf(void);
#ifdef __cplusplus
}
#endif
#endif // TABLERO_H_
Header files like this have to be extra careful to contain only code that has the same meaning in C and C++. Only POD types, no C++ keywords, no C99-but-not-C++ keywords either, no overloads, et cetera.

Related

Header file not working (source file not compiled) c language

In my header file file.h I have:
#ifdef FILE_H
extern "C" {
#endif
int size;
int array[3];
void saveToFile();
void loadFromFile();
#ifdef FILE_H
}
#endif
After I try compiling it, table with "Source file not compiled" pops up and I also get warning like this command line option '-std=c99' is valid for C/ObjC but not for C++.
In my file.c I have:
#include <stdio.h>
#include <stdlib.h>
#include "file.h"
void saveToFile(){
FILE *load=fopen("1uzd.txt", "w");
int array[3];
fprintf(load, "%d ", 3);
array[0]=1;
array[1]=2;
array[2]=3;
for(int i=0; i<3; i++){
fprintf(load, "%d ", array[i]);
}
fclose(load);
}
void loadFromFile(){
FILE *load=fopen("1uzd.txt", "r");
int size;
fscanf(load, "%d", &size);
int array[size];
for(int i=0; i<size; i++){
fscanf(load, "%d", &array[i]);
}
printf("%d %d %d", size, array[0], array[1]);
}
And undefined reference to `WinMain' with ld returned 1 exit status
And in main.c:
#include <stdlib.h>
#include <stdio.h>
#include "file.h"
int main(void){
saveToFile();
loadFromFile();
return 0;
}
With undefined reference to saveToFile', undefined reference to loadFromFile' and ld returned 1 exit status.
In my header file file.h I have:
#ifdef FILE_H
extern "C" {
#endif
int size;
int array[3];
void saveToFile();
void loadFromFile();
#ifdef FILE_H
}
#endif
Your multi-inclusion guards have the wrong sense and scope. Also, if your intention is for this header to be usable in both C and C++, then the extern "C" declaration is incorrectly protected. Perhaps you want this:
#ifndef FILE_H
#define FILE_H
#ifdef __cplusplus
extern "C" {
#endif
int size;
int array[3];
void saveToFile();
void loadFromFile();
#ifdef __cplusplus
}
#endif
#endif
That provides for
the contents of the header to be considered only the first time the header is included in any translation unit, and
the extern "C" declaration to be ignored unless the header is being processed by a C++ compiler.
After I try compiling it, table with "Source file not compiled" pops
up and I also get warning like this command line option '-std=c99' is
valid for C/ObjC but not for C++.
One does not compile headers directly. One uses #include directives to incorporate their contents into other sources. The source files you present contain such #include directives, so you should not need to do anything further in that regard.
In my file.c I have [...] undefined reference to `WinMain'
You are trying to compile file.c as a complete program, but that doesn't work because it does not have a main() function.
And in main.c [...] undefined reference to saveToFile', undefined reference to loadFromFile'
You are trying to compile main.c as a complete program, but it does not contain the source of a complete program because it calls functions that are defined in a different source file.
There are two main approaches you could take:
compile each .c file to an object file and then link them together into a whole program in a separate step, or
compile both .c files in a single compilation command.
Details of both options depend on the compiler and build system used. Some of your diagnostic messages suggest GCC to me, and with GCC running in command-line mode, the latter would be something like
gcc -std=c99 -o my_program.exe main.c file.c
. The "my_program.exe" is the name you want your executable to have. The -std=c99 is necessary with your code for some versions of GCC, and the diagnostics suggest that it appears in the command-line arguments you are actually using. You may include other command-line options, too, if you wish.
Note also that you must use a C compiler to compile C code, not a C++ compiler. Your diagnostics suggest that you may be trying to use the latter. C and C++ are different languages. Although they have a shared subset, neither is a superset of the other.

How to create a C library with CodeBlocks?

How can I create a C library in CodeBlocks that can be define and used like a standard library with the #include command?
In fact I want to create a simple library that is Composed of several functions.
Basically, you need a .h file for the header definitions and a .c containing the source code.
An example:
/* command.h */
#ifndef COMMAND_H
#define COMMAND_H
int func(void);
#endif /* COMMAND_H */
/* command.c */
#include "command.h"
int func(void)
{
return 0;
}
/* main.c */
#include <stdio.h>
#include "command.h"
int main(void)
{
printf("%d\n", func());
return 0;
}
ifndef is used to prevent the file from being included more than once.
Compile it including both .c files in the command line:
gcc -o demo main.c command.c
Or in your case, follow this guide to compile multiple files in codeblocks.

Calling #define from another file

This is my code. I have file1.c and file2.c. I want to call the MESSAGE from file2.c but I can't seem to do it. I am newbie in C so I really don't know what to do. I researched already but, I can't seem to find a specific answer. Thankyou.
#define MESSAGE "this is message!"
helloworld(){
printf("%s",MESSAGE);
getch();
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file2.c"
int main(void)
{
helloworld();
}
There are a few misconceptions you have: First of all the concept of "calling" a macro. It's not possible, even if a macro looks like a function it's not a function and macros are not actually handled by the compiler. Instead macros are part of a separate language that is handled by a preprocessor, which takes the source file and modifies it to generate a translation unit that the compiler sees. (For more information about the difference phases of "compilation" see e.g. this reference.)
The preprocessor does this by basically doing a search-replace in the input source file: When it sees a macro "invocation" it simply replaces that with the "body" of the macro. When it sees an #include directive, it preprocesses the file and then puts the content in place of the directive.
So in your code, when the preprocessor sees the macro MESSAGE it is literally replaced by "this is message!". The actual compiler doesn't see MESSAGE at all, it only sees the string literal.
Another misconception is how you use the #include directive. You should not use it to include source files. Instead you compile the source files separately (which creates object files) and then link the generated object files together with whatever libraries are needed to form the final executable.
To solve the problem of macros (and other declarations) being available to all source files, you use header files. These are like source files, but only contains declarations and macros. You then include the header file in both source files, and both source files will know about the declarations and macros available in the header file.
So in your case you should have three files: The main source file, the source file containing the function, and a header file containing the macro and the function declaration (also known as a prototype). Something like
Header file, e.g. header.h:
// First an include guard (see e.g. https://en.wikipedia.org/wiki/Include_guard)
#ifndef HEADER_H
#define HEADER_H
// Define the macro, if it needs to be used by all source files
// including this header file
#define MESSAGE "this is message!"
// Declare a function prototype so it can be used from other
// source files
void helloworld();
#endif
Main source file, e.g. main.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
int main(void)
{
// Use the macro
printf("From main, MESSAGE = %s\n", MESSAGE);
// Call the function from the other file
helloworld();
}
The other file, e.g. hello.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
void helloworld(void)
{
printf("Hello world!\n");
printf("From helloworld, MESSAGE = %s\n", MESSAGE);
}
Now, if you use a command-line compiler like gcc or clang then you can simply build it all by doing e.g.
$ gcc -Wall main.c hello.c -o myhello
That command will take the two source files, main.c and hello.c and run the preprocessor and compiler on them to generate (temporary) object files. These object files are then linked together with the standard C library to form the program myhello (that's what the option -o does, names the output file).
You can then run myhello:
$ ./myhello
From main, MESSAGE = this is message!
Hello world!
From helloworld, MESSAGE = this is message!
In your file1.c, MESSAGE is a preprocessor macro, which means the text MESSAGE will be replaced with the string "this is message!". It is not visible outside the file. This is because in C, translation units are the final inputs to the compiler, and thes translation units already have all of preprocessor macros replaced by the tokens of the corresponding argument.
If you want to have a common variable, you should declare the variable as extern in a .h header file, and then #include the file where you need to use it.
see Compiling multiple C files in a program
You have to put your #define in a .h file and include it in .c files where you want to use it.
You can write the files as below and compile the code as i mention in the following steps.
file1.h
#ifndef _FILE1_H
#define _FILE1_H
#define MESSAGE "this is message!"
extern void helloworld();
#endif
file1.c
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
file2.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
return 0;
}
For compiling,
gcc -Wall file1.c file2.c -o myprog
./myprog
Here is code try this:
In File1.C
#define FILE1_C
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
In File2.C
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
}
In File1.h
#ifdef FILE1_C
#define MESSAGE "this is message!"
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN helloword()

C preprocessor Result

Which result does return this construct? I mean the result variable in main-function, and why?
I know, that the example is very strange ;)
header1.h file:
extern const int clf_1;
header2.c file:
#include "header1.h"
const int clf_1 = 2;
test.h file:
#include <header1.h>
#define xyz clf_1
#define NC_CON 2
#if (xyz== NC_CON)
#define test 40
#else
#define test 41
#endif
C file
#include <header1.h>
#include <test.h>
int main(int argc,char *argv[])
{
int result = 0:
if (test == 40)
{
result = 40;
}
}
Read the wikipage on the C preprocessor and the documentation of GNU cpp (the preprocessor inside GCC, i.e run by gcc or g++ etc...). It is a textual thing, and it is run before the definition const int clf_1 = 2; has been processed by the compiler. A #if directive only makes sense if all the names appearing in it are preprocessor symbols (defined with #define or with -D passed on the command line of the GCC or Clang/LLVM compiler)
Use gcc -C -E yoursource.c > yoursource.i (with some other options after gcc, probably -I. is needed ... you should #include "header1.h"
etc...) then look with an editor or a pager into the generated yoursource.i (the preprocessed form)
The world would be very different if the C preprocessor transformed ASTs; for historical reasons, the first C preprocessors were textual filters (run as a different program).

Duplicate symbol in C using Clang

I am currently working on my first "serious" C project, a 16-bit vm. When I split up the files form one big source file into multiple source files, the linker (whether invoked through clang, gcc, cc, or ld) spits out a the error:
ld: duplicate symbol _registers in register.o and main.o for inferred
architecture x86_64
There is no declaration of registers anywhere in the main file. It is a uint16_t array if that helps. I am on Mac OS 10.7.3 using the built in compilers (not GNU gcc). Any help?
It sounds like you've defined a variable in a header then included that in two different source files.
First you have to understand the distinction between declaring something (declaring that it exists somewhere) and defining it (actually creating it). Let's say you have the following files:
header.h:
void printIt(void); // a declaration.
int xyzzy; // a definition.
main.c:
#include "header.h"
int main (void) {
xyzzy = 42;
printIt();
return 0;
}
other.c:
#include <stdio.h>
#include "header.h"
void printIt (void) { // a definition.
printf ("%d\n", xyzzy);
}
When you compile the C programs, each of the resultant object files will get a variable called xyzzy since you effectively defined it in both by including the header. That means when the linker tries to combine the two objects, it runs into a problem with multiple definitions.
The solution is to declare things in header files and define them in C files, such as with:
header.h:
void printIt(void); // a declaration.
extern int xyzzy; // a declaration.
main.c:
#include "header.h"
int xyzzy; // a definition.
int main (void) {
xyzzy = 42;
printIt();
return 0;
}
other.c:
#include <stdio.h>
#include "header.h"
void printIt (void) { // a definition.
printf ("%d\n", xyzzy);
}
That way, other.c knows that xyzzy exists, but only main.c creates it.

Resources