C preprocessor directive error - c

I have a problem when i want use his scripts:
lib1.h
...
#ifdef LIB1_01
int lib1func(void);
#endif
...
lib1.c
...
#ifdef LIB1_01
int lib1func(void){
...
}
#endif
...
main.c
#define LIB1_01
#include <lib1.h>
int main(){
...
int x = lib1func(void);
...
...
I want use lib1func() when #define LIB1_01 is declared but I have an 'warning : implicit declaration of function' error when i use it...why ? Can you help me ?
Best regards.

Recommended alternative:
lib1.h
#ifndef LIB1_H
#define LIB1_H
int lib1func(void);
#endif
...
lib1.c
#include "lib1.h"
int lib1func(void){
...
}
main.c
#include "lib1.h"
int main(){
...
int x = lib1func(void);
...
...
NOTE:
1) You should declare "int lib1func(void)" in the header, but you may define it anywhere. In lib1.c (if you prefer), or even main.c. Just make sure you only define it once.
2) Note the use of the guard around the entire header body.
3) Also note the use of include "myheader.h" (for your own header files), vs. #include <systemheader.h>. The "<>" syntax should be used only for system headers.

To use that kind of includes, compile with option I.
gcc myfile.c -o myfile -I .
The . symbol means look in the current directory.

Related

How can I link multiple c-files together using headers?

I work on a project that has multiple c files. Each c file has its own header. Now I want to put all c files together.
As a preperation I have tried the following thing:
This would be my example c-code (function.c):
#include <stdio.h>
#include "function.h"
void output()
{
printf("Thats a text\n");
}
Thats the associated header file (function.h):
//header function.h
#ifndef FUNCTION_H_
#define FUNCTION_H_
#endif // FUNCTION_H_
And thats my main.c:
#include "function.h"
int main()
{
output();
return 0;
}
I would expect the following output:
"Thats a text"
But I only receive following error:
undefined reference to 'output'
What am I doing wrong here?
Thanks a lot!
You need the prototype for output function in your header so that it's visible in other module(s).
//header function.h
#ifndef FUNCTION_H_
#define FUNCTION_H_
void output(void);
#endif // FUNCTION_H_
And you need to link the module (source file function.c) in order to actually provide the definition of output that your main module uses.
For example, you can directly compile them together with:
gcc main.c function.c -o my_out
You may also want to look at Makefiles as well.
Your header should be
//header function.h
#ifndef FUNCTION_H_
#define FUNCTION_H_
void output();
#endif // FUNCTION_H_
compile like this:
(actual flags may depend on compiler used)
cc -c main.c
(creates main.o)
cc -c function.c
(creates function.o)
cc main.o function.o
(creates a.out or whatever your system default is)
...or as someone else mentioned:
cc main.c function.c
(does it all)

C preprocessor #error in header file included in multiple source files

I have two source files, main.c and datamgr.c - and two header files, config.h and datamgr.h
The testing system we're using expects these files, and only these files.
main.c:
#include "datamgr.h"
#include "config.h"
int main() {
custom_type a = 1;
a = foo();
return 0;
}
datamgr.c:
#include "datamgr.h"
#include "config.h"
custom_type foo() {
custom_type a = 1;
return a;
}
datamgr.h:
#ifndef DATAMGR_H
#define DATAMGR_H
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
custom_type foo();
#endif
config.h:
#ifndef CONFIG_H
#define CONFIG_H
#ifndef SET_MAX_TEMP
#error "Max temperature not set."
#endif
#ifndef SET_MIN_TEMP
#error "Max temperature not set."
#endif
typedef custom_type uint16_t
#endif
Now, the problem is that I can only define SET_MAX_TEMP and SET_MIN_TEMP in main.c, but both main.c and datamgr.c need both the header files. So if I leave them undefined in datamgr.c I get a compiler error. However, if I do define them in datamgr.c and later overwrite them in main.c, I get a different compiler error.
Please, any assistance as to how to get this horrible setup to work would be greatly appreciated.
You can pass these defines directly while compiling:
gcc -DSET_MAX_TEMP -DSET_MIN_TEMP <your files>
In datamgr.c do:
#define SET_MAX_TEMP
#define SET_MIN_TEMP
#include "datamgr.h"
#include "config.h"
#undef SET_MAX_TEMP
#undef SET_MIN_TEMP
In a comment, you said:
Because main.c is the file that our testing system uses to implement the test scenarios.
In that case, make sure that the testing system defines those macros in the command line of the compiler for every file being compiled.

Setting function at specific address

I have the next single C code and I'm trying to compile for arm using arm-gcc GNU and eclipse.
main.h
#ifndef
#define MAIN_H_
extern int rmain(int,int);
#endif
main.c
#include main.h
#include sum.h
int rmain(a1,a2){
int z=0x89;
return sum(a1+a2)+z;
sum.h
#ifndef
#define SUM_H_
extern int sum(int,int);
#endif
sum.c
#include sum.h
int sum(int a1,int a2)
return a1+a2;
My linker script file look like on this way:
mem.lds
ENTRY(rmain)
SECTIONS:{
.=0x808080
.text:{*(.text)}
.data:{*(.data)}
.bss:{*(.bss)}
}
This work OK, but my problem is that I need that function rmain will be set at 0x808080 address, so How i can do it this ?
I tryed with:
SECTIONS:{
.=0x808080
.start:{main.o (.text)}
.text:{*(EXCLUDE_FILE(main.o).text)}
.data:{*(.data)}
.bss:{*(.bss)}
}
But not luck linker say: multiple definition of rmain.

Unresolved External Symbol with external get function

I keep getting a linker error with the following setup.
I have file1.c which contains the following code
#if defined( _TEST_ENABLED )
int get_value()
{
.
.
.
}
#endif /*_TEST_ENABLED */
I have file2.c which includes file2.h, which defines _TEST_ENABLED. file2.c makes a call to get_value(), however the linker isn't having any part of that.
I've exhausted a lot of different options with zero success. Now i'm asking for help :)
If file1.c does not include file2.h or any file which defines _TEST_ENABLED, _TEST_ENABLED will not be defined when the preprocessor runs on file1.c, so int get_value() { ... } will not get compiled.
In order to call a function in another file:
1) The files must be compiled or at least linked together. The easiest way to do this is gcc file1.c file2.c, however you can also compile both files to *.o files and then link together.
2) The calling file must have, usually through an included header, a prototype of the function. This prototype must appear before the function is used. So, if file2.h defines _TEST_ENABLED, then you must (in file2.c) include file2.h, and then either file2.c or file2.h must include file1.h, which must contain a function prototype (int get_value;)
For example:
file1.c
#include <file1.h>
#include <file2.h>
int main() {
get_value();
}
file1.h
#ifndef _FILE2_H
#define _FILE2_H
#define _TEST_ENABLED
#endif
file2.c
#include <file2.h>
#include <file1.h>
#ifdef _TEST_ENABLED
int get_value() {
return 42;
}
#endif
file2.h
#ifndef _FILE2_H
#define _FILE2_H
int get_value();
#endif
Note that for the purposes of the preprocessor, file1.c and file2.c are processed completely separately. When processing file2.c, it MUST find #define _TEST_ENABLED somewhere, which is why file2.c must include file1.h. Since this is getting a little circular, you should add "#include-guards to each header file, as shown above.
There are some ambiguities in your question, but given the following three files, I can compile and build in ANSI C, but I have to include the .h in both .cs:
file1.c
#include "file2.h"
int main(void)
{
someFunc();
get_value();
return 0;
}
#ifdef _TEST_ENABLED
int get_value(void)
{
return 0;
}
#endif
file2.c
#include "file2.h"
int someFunc(void);
int someFunc(void)
{
get_value();
return 0;
}
file2.h
#define _TEST_ENABLED
int get_value(void);

Header/Include guards don't work?

For some reason, I'm getting multiple declarations of content within my header file even though I'm using header guards. My example code is below:
main.c:
#include "thing.h"
int main(){
printf("%d", increment());
return 0;
}
thing.c:
#include "thing.h"
int increment(){
return something++;
}
thing.h:
#ifndef THING_H_
#define THING_H_
#include <stdio.h>
int something = 0;
int increment();
#endif
When I attempt to compile this, GCC says that I have multiple definitions of the something variable. ifndef should make sure that this doesn't happen, so I'm confused why it is.
The include guards are functioning correctly and are not the source of the problem.
What happens is that every compilation unit that includes thing.h gets its own int something = 0, so the linker complains about multiple definitions.
Here is how you fix this:
thing.c:
#include "thing.h"
int something = 0;
int increment(){
return something++;
}
thing.h:
#ifndef THING_H_
#define THING_H_
#include <stdio.h>
extern int something;
int increment();
#endif
This way, only thing.c will have an instance of something, and main.c will refer to it.
You have one definition in each translation unit (one in main.c, and one in thing.c). The header guards stop the header from being included more than once in a single translation unit.
You need to declare something in the header file, and only define it in thing.c, just like the function:
thing.c:
#include "thing.h"
int something = 0;
int increment(void)
{
return something++;
}
thing.h:
#ifndef THING_H_
#define THING_H_
#include <stdio.h>
extern int something;
int increment(void);
#endif
The header guards will stop the file from being compiled more than once in the same compilation unit (file). You are including it in main.c and thing.c, so it will be compiled once in each, leading to the variable something being declared once in each unit, or twice in total.
try to avoid defining variables globally.
use functions like increment() to modify and read its value instead.
that way you can keep the variable static in the thing.c file, and you know for sure that only functions from that file will modify the value.
The variable something should be defined in a .c file, not
in a header file.
Only structures, macros and type declarations for variables and function prototypes
should be in header files. In your example, you can declare the type of something as extern int something in the header file. But the definition of the variable itself should be in a .c file.
With what you have done, the variable something will be defined
in each .c file that includes thing.h and you get a
"something defined multiple times" error message when GCC tries to link
everything together.
what ifndef is guarding is one .h included in a .c more than once. For instance
thing. h
#ifndef
#define
int something = 0;
#endif
thing2.h
#include "thing.h"
main.c
#include "thing.h"
#include "thing2.h"
int main()
{
printf("%d", something);
return 0;
}
if I leave ifndef out then GCC will complain
In file included from thing2.h:1:0,
from main.c:2:
thing.h:3:5: error: redefinition of ‘something’
thing.h:3:5: note: previous definition of ‘something’ was here

Resources