how do i avoid this linking error? - c

if i have defined a global variable(with initialization) in header file, and included this file in two file and try to compile and link, compiler gives linking error
headers.h:
#ifndef __HEADERS
#define __HEADERS
int x = 10;
#endif
1.c:
#include "headers.h"
main ()
{
}
2.c:
#include "headers.h"
fun () {}

The linker complains because there will be multiple definitions of x once it puts all the object files together to create the executable. You have two different source files including the same header file, and that header file defines a variable x having a value of 10, so you end up with two definitions of x (one in 1.c and another in 2.c).
To avoid multiple definition linker errors, put this in a header file (for example globals.h):
#ifndef GLOBALS_H
#define GLOBALS_H
/*
* The "extern" keyword means that this variable is accessible everywhere
* as long as this declaration is present before it is used. It also means
* that the variable x may be defined in another translation unit.
*/
extern int x;
#endif
Then put this in one source file:
#include "globals.h"
int x = 10;

This is a classic case where you want either the variable declared or declared-and-defined.
If you define it in both source files, you will get a double-definition linker error. One way to handle this is to only set __HEADERS for one of the source files so that it is the one where the variable is defined.
All other source files get the declaration only.
>>headers.h
#ifndef __HEADERS
int x = 10;
#else
extern int x;
#endif
>>1.c
#define __HEADERS
#include "headers.h"
int main (void) {
return 0;
}
>>2.c
#include "headers"
void fun (void) {
}
Of course, it's best to leave definitions out of header files altogether in case you accidentally define __HEADERS in two source files. Try:
>>headers.h
extern int x;
>>1.c
#include "headers.h"
int x = 10;
int main (void) {
return 0;
}
>>2.c
#include "headers"
void fun (void) {
}

#include works exactly the same as if you copied and pasted the text from the header file.
Consider it in that way and you will see that you have therefore put the line int x=10 into both your source files.
A fixed version is below:
>>headers.h
#ifndef __HEADERS
#define__HEADERS
extern int x; // extern tells the compiler it will be linked from another file
#endif
-----------------
>>1.c
#include "headers.h"
int x = 10; // must have it in ONE file for linking purposes
main ()
{
}
---------------------
>>2.c
#include "headers"
fun () {}

Define __HEADERS in the ifndef.
Put declarations, not definitions, in your headers:
// header
extern int x;
// implementation
int x = 10;
3. 2.c has the include wrong.
So:
// headers.h
#ifndef __HEADERS
#define __HEADERS
extern int x;
#endif
// 1.c
#include "headers.h"
int x = 10;
main ()
{
}
// 2.c
#include "headers.h"
fun () {}
You can define x anywhere. Just make it one place.

Related

How to define constants in headers to use in multiple C files

When writing C code, I might want to define a constant array in a header file so that it may be used in multiple .c files.
Take the following example:
main.c
#include <stdio.h>
#include "main.h"
int main() {
int localmat[9];
for (int i = 0; i < 9; i++) {
localmat[i] = HEADERMAT[i];
}
matadd(localmat, HEADERMAT);
return 0;
}
main.h
#ifndef _MAIN_H_
#define _MAIN_H_
// Constant array
const int HEADERMAT[9] = {0,1,2,3,4,5,6,7,8};
// prototype function:
void matadd(int matA[9], const int matB[9]);
#endif
functions.c
#include "main.h"
void matadd(int matA[9], const int matB[9]){
for (int i = 0; i < 9; i++) {
matA[i] += matB[i];
}
}
The constant array HEADERMAT declared in main.h is used in both
main.c and functions.h. The header does use ifndef to prevent redefinitions and yet, the compiler will still complain about it being defined multiple times:
/usr/bin/ld: /tmp/ccVWhI0u.o:(.rodata+0x0): multiple definition of `HEADERMAT'; /tmp/ccRAIQ5u.o:(.rodata+0x0): first defined here
collect2: error: ld returned 1 exit status
What would be the better way of making this array accessible to both C files?
Header files are for declarations. So, this is one way:
// main.h
#ifndef _MAIN_H_
#define _MAIN_H_
// Constant array
const int HEADERMAT[9]; // <---- declaration only
// prototype function:
void matadd(int matA[9], const int matB[9]);
#endif
Then, in some source file (preferably main.c, since we declared in main.h)
// main.c
#include <stdio.h>
#include "main.h"
const int HEADERMAT[9] = {0,1,2,3,4,5,6,7,8}; // <---- definition here
int main() {
int localmat[9];
for (int i = 0; i < 9; i++) {
localmat[i] = HEADERMAT[i];
}
matadd(localmat, HEADERMAT);
return 0;
}
If you did it this way in the header file instead:
// main.h
// main.h
#ifndef _MAIN_H_
#define _MAIN_H_
// Constant array
static const int HEADERMAT[9] = {0,1,2,3,4,5,6,7,8}; // <-- static definition
// prototype function:
void matadd(int matA[9], const int matB[9]);
#endif
Then the array would be duplicated in every source file that included main.h, which, as the Jonathan Leffler's comments point out, is not that big of a deal (36 bytes). But for an array of appreciable size, the waste would be a concern.
If I understand you simply want to make the HEADERMAT[] array available in multiple source files, you can simply declare it as usual in any of the source files and then declare it as extern in any other source file that needs it.
To do so, you need to
define a macro for the array size in a common header so all sources will know the size of the array, e.g. #define HEADERMATSZ 9,
declare the array as usual in one of the C source files, e.g. const int HEADERMAT[HEADERMATSZ] = {0,1,2,3,4,5,6,7,8};,
in any other C source files that need access, declare extern const int HEADERMAT[HEADERMATSZ];.
Now you can simply use HEADERMAT[] as needed in any file where it is either declared originally, or as extern.
A short example, first the common header to be included by main.c and source1.c that holds a function that will use the array declared as extern, e.g.
#ifndef COMMONHDR
#define COMMONHDR 1
#define HEADERMATSZ 9 /* defined size of extern array */
void showoutput (void); /* declaration of function using extern array*/
#endif
For your main.c we will declare the array there, including the common header to provide the declaration for the function we will call from source1.c that uses the array declared extern, e.g.
#include <stdio.h>
#include "commonhdr.h"
const int HEADERMAT[HEADERMATSZ] = {0,1,2,3,4,5,6,7,8};
int main (void) {
puts ("output from other file");
showoutput();
}
(the showoutput() function being the function called from source1.c, also note HEADERMATSZ can be omitted if your initializer has the correct number of values -- including it ensures the array is sized correctly)
Finally the source1.c file we provide the function definition that uses the array extern,
#include <stdio.h>
#include "commonhdr.h"
extern const int HEADERMAT[HEADERMATSZ];
/* definition of function using extern array */
void showoutput (void)
{
for (int i = 0; i < HEADERMATSZ; i++) {
printf (" %d %d\n", i, HEADERMAT[i]);
}
}
Compile both sources into the final executable, e.g. with gcc,
gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast source1.c -o main main.c
Example Use/Output
$ ./main
output from other file
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
This method works well regardless whether it is on your PC or programming a micro-controller. By using extern, the array need not be const and can be modified in either source if it is mutable.

how to share functions in c [duplicate]

Can anyone explain how to create a header file in C with a simple example from beginning to end.
foo.h
#ifndef FOO_H_ /* Include guard */
#define FOO_H_
int foo(int x); /* An example function declaration */
#endif // FOO_H_
foo.c
#include "foo.h" /* Include the header (not strictly necessary here) */
int foo(int x) /* Function definition */
{
return x + 5;
}
main.c
#include <stdio.h>
#include "foo.h" /* Include the header here, to obtain the function declaration */
int main(void)
{
int y = foo(3); /* Use the function here */
printf("%d\n", y);
return 0;
}
To compile using GCC
gcc -o my_app main.c foo.c
#ifndef MY_HEADER_H
# define MY_HEADER_H
//put your function headers here
#endif
MY_HEADER_H serves as a double-inclusion guard.
For the function declaration, you only need to define the signature, that is, without parameter names, like this:
int foo(char*);
If you really want to, you can also include the parameter's identifier, but it's not necessary because the identifier would only be used in a function's body (implementation), which in case of a header (parameter signature), it's missing.
This declares the function foo which accepts a char* and returns an int.
In your source file, you would have:
#include "my_header.h"
int foo(char* name) {
//do stuff
return 0;
}
myfile.h
#ifndef _myfile_h
#define _myfile_h
void function();
#endif
myfile.c
#include "myfile.h"
void function() {
}
header files contain prototypes for functions you define in a .c or .cpp/.cxx file (depending if you're using c or c++). You want to place #ifndef/#defines around your .h code so that if you include the same .h twice in different parts of your programs, the prototypes are only included once.
client.h
#ifndef CLIENT_H
#define CLIENT_H
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);
#endif /** CLIENT_H */
Then you'd implement the .h in a .c file like so:
client.c
#include "client.h"
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
short ret = -1;
//some implementation here
return ret;
}

How to declare parameters in C

I have a bunch of parameters (integers and floats); I want to write a C code where both the main program and the functions refer to the same parameters so that if I change one of them the whole code knows the new value I set. My code is formed by a main.c file which calls a function.c file; right now I declared the parameters both in the main and in the function but I think that is not robust (if I change one parameters in the main and I forget to change it also in the function I get wrong results). So here is the question: How can declare the parameters in order to change it just once and not to change it everywhere I have defined?
PS: i don't want to use #define because it doesn't allow me to specify whether it's an integer or not.
You can use a global variable, define it at the top of the main.c file and refer it at the top of the other .c file using the declaration "extern".
main.c
#include
...
int a;//global variable
function.c
include ...
extern int a;//global variable
You can use global variables.
Create a .h files -- let's call it globals.h. Put declarations of the global variables in the file.
extern int var1;
extern float var2;
extern double var3;
Create a .c file -- let's call it globals.c. Define the variables in the file.
#include "globals.h"
int var1 = 0;
float var2 = 10.0f;
double var3 = 200.0;
Use #include "globals.h" in any .c file in which you want to access the global variable.
#include "globals.h"
int main()
{
printf("var1 : %d\n", var1);
printf("var2 : %f\n", var2);
printf("var3 : %lf\n", var3);
}
If you change the values of var1, var2, or var3 anywhere in the program, the change will take effect for all the functions that access them.
You could use static consts, to all intents and purposes your effect will be achieved.
myext.h:
#ifndef _MYEXT_H
#define _MYEXT_H
static const int myx = 245;
static const unsigned long int myy = 45678;
static const double myz = 3.14;
#endif
myfunc.h:
#ifndef MYFUNC_H
#define MYFUNC_H
void myfunc(void);
#endif
myfunc.c:
#include "myext.h"
#include "myfunc.h"
#include <stdio.h>
void myfunc(void)
{
printf("%d\t%lu\t%f\n", myx, myy, myz);
}
myext.c:
#include "myext.h"
#include "myfunc.h"
#include <stdio.h>
int main()
{
printf("%d\t%lu\t%f\n", myx, myy, myz);
myfunc();
return 0;
}

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

Creating your own header file in C

Can anyone explain how to create a header file in C with a simple example from beginning to end.
foo.h
#ifndef FOO_H_ /* Include guard */
#define FOO_H_
int foo(int x); /* An example function declaration */
#endif // FOO_H_
foo.c
#include "foo.h" /* Include the header (not strictly necessary here) */
int foo(int x) /* Function definition */
{
return x + 5;
}
main.c
#include <stdio.h>
#include "foo.h" /* Include the header here, to obtain the function declaration */
int main(void)
{
int y = foo(3); /* Use the function here */
printf("%d\n", y);
return 0;
}
To compile using GCC
gcc -o my_app main.c foo.c
#ifndef MY_HEADER_H
# define MY_HEADER_H
//put your function headers here
#endif
MY_HEADER_H serves as a double-inclusion guard.
For the function declaration, you only need to define the signature, that is, without parameter names, like this:
int foo(char*);
If you really want to, you can also include the parameter's identifier, but it's not necessary because the identifier would only be used in a function's body (implementation), which in case of a header (parameter signature), it's missing.
This declares the function foo which accepts a char* and returns an int.
In your source file, you would have:
#include "my_header.h"
int foo(char* name) {
//do stuff
return 0;
}
myfile.h
#ifndef _myfile_h
#define _myfile_h
void function();
#endif
myfile.c
#include "myfile.h"
void function() {
}
header files contain prototypes for functions you define in a .c or .cpp/.cxx file (depending if you're using c or c++). You want to place #ifndef/#defines around your .h code so that if you include the same .h twice in different parts of your programs, the prototypes are only included once.
client.h
#ifndef CLIENT_H
#define CLIENT_H
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);
#endif /** CLIENT_H */
Then you'd implement the .h in a .c file like so:
client.c
#include "client.h"
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
short ret = -1;
//some implementation here
return ret;
}

Resources