The setup
If I have a program like this
A header file that declares my main library function, primary() and defines a short simple helper function, helper().
/* primary_header.h */
#ifndef _PRIMARY_HEADER_H
#define _PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary();
/* Also define a helper function */
void helper()
{
printf("I'm a helper function and I helped!\n");
}
#endif /* _PRIMARY_HEADER_H */
The implementation file for my primary function that defines it.
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
a main() file that tests the code by calling primary()
/* main.c */
#include "primary_header.h"
int main()
{
/* just call the primary function */
primary();
}
The Problem
Using
gcc main.c primary_impl.c
does not link because the primary_header.h file gets included twice and therefore there is an illegal double definition of the function helper(). What is the correct way to structure the source code for this project such that double definitions do not happen?
You should only write your function's prototype in the header file, the body of your function should be written in a .c file.
Do this :
primary_header.h
/* primary_header.h */
#ifndef PRIMARY_HEADER_H
#define PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary(void);
/* Also define a helper function */
void helper(void);
#endif /* PRIMARY_HEADER_H */
primary_impl.c
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
void helper()
{
printf("I'm a helper function and I helped!\n");
}
Edit: change _PRIMARY_HEADER_H to PRIMARY_HEADER_H. As #Jonathan Leffler and #Pablo said, underscore names are reserved identifiers
You almost never write a function inside a header file unless it is marked to always be inlined. Instead, you write the function in a .c file and copy the function's declaration (not definition) to the header file so it can be used elsewhere.
You can define a function in header files if it's weak linkage like:
// test.h
__attribute__((weak)) int test() {
static int s = 0;
return s++;
}
// a.c
#include "test.h"
#include <stdio.h>
void a(){
print("%d", test());
}
// b.c
#include "test.h"
#include <stdio.h>
void b(){
print("%d", test());
}
// main.c
#include "test.h"
#include <stdio.h>
void a();
void b();
void main(){
a();
b();
print("%d", test());
}
cc a.c b.c main.c won't raise multiple definitions error and the output should be 012 as expected, meaning a.c, b.c and main.c share the same test function.
You can achieve the same result in c++ by using inline.
Moreover, weak linkage can also be used on variable definition, allowing you to define and initialize a global variable in header files without source files (similar to inline static in c++).
Note:
Weak symbols are not mentioned by the C or C++ language standards.
So be careful when using it in c. But in c++, inline and inline static are portable form c++11 and c++17.
Related
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;
}
The setup
If I have a program like this
A header file that declares my main library function, primary() and defines a short simple helper function, helper().
/* primary_header.h */
#ifndef _PRIMARY_HEADER_H
#define _PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary();
/* Also define a helper function */
void helper()
{
printf("I'm a helper function and I helped!\n");
}
#endif /* _PRIMARY_HEADER_H */
The implementation file for my primary function that defines it.
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
a main() file that tests the code by calling primary()
/* main.c */
#include "primary_header.h"
int main()
{
/* just call the primary function */
primary();
}
The Problem
Using
gcc main.c primary_impl.c
does not link because the primary_header.h file gets included twice and therefore there is an illegal double definition of the function helper(). What is the correct way to structure the source code for this project such that double definitions do not happen?
You should only write your function's prototype in the header file, the body of your function should be written in a .c file.
Do this :
primary_header.h
/* primary_header.h */
#ifndef PRIMARY_HEADER_H
#define PRIMARY_HEADER_H
#include <stdio.h>
/* Forward declare the primary workhorse function */
void primary(void);
/* Also define a helper function */
void helper(void);
#endif /* PRIMARY_HEADER_H */
primary_impl.c
/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>
/* Define the primary workhorse function */
void primary()
{
/* do the main work */
printf("I'm the primary function, I'm doin' work.\n");
/* also get some help from the helper function */
helper();
}
void helper()
{
printf("I'm a helper function and I helped!\n");
}
Edit: change _PRIMARY_HEADER_H to PRIMARY_HEADER_H. As #Jonathan Leffler and #Pablo said, underscore names are reserved identifiers
You almost never write a function inside a header file unless it is marked to always be inlined. Instead, you write the function in a .c file and copy the function's declaration (not definition) to the header file so it can be used elsewhere.
You can define a function in header files if it's weak linkage like:
// test.h
__attribute__((weak)) int test() {
static int s = 0;
return s++;
}
// a.c
#include "test.h"
#include <stdio.h>
void a(){
print("%d", test());
}
// b.c
#include "test.h"
#include <stdio.h>
void b(){
print("%d", test());
}
// main.c
#include "test.h"
#include <stdio.h>
void a();
void b();
void main(){
a();
b();
print("%d", test());
}
cc a.c b.c main.c won't raise multiple definitions error and the output should be 012 as expected, meaning a.c, b.c and main.c share the same test function.
You can achieve the same result in c++ by using inline.
Moreover, weak linkage can also be used on variable definition, allowing you to define and initialize a global variable in header files without source files (similar to inline static in c++).
Note:
Weak symbols are not mentioned by the C or C++ language standards.
So be careful when using it in c. But in c++, inline and inline static are portable form c++11 and c++17.
I'm aware of the declaration of C header files with #ifdef and the meaning of extern before variables and functions. But recently I've got a third party library for an embedded device with the following scheme:
/* "lib.h" */
#ifndef LIB_H_
#define LIB_H_
#ifdef LIB_C
void function1();
/* ... */
#else
extern void function1();
/* ... */
#endif
#endif /* LIB_H_ */
And additionally I've got a corresponding C source file:
/* lib.c */
#define LIB_C
#include "lib.h"
void function1()
{
/* ... */
}
/* ... */
So here I am and a bit confused. What is the reason to declare all functions twice in the header in this way?
It's either an affectation, or a compatibility hack for some non-conforming or ancient compiler. You don't need the extern version, but using it is also fine, because function declarations are extern by default.
In other words, it's cruft, but maybe someone needs that cruft. We can't know for sure.
Lets say I have a main.c file
#include "library.h"
#define LIBRARY_VALUE 5
int main(void)
{
somefunction1();
return 0;
}
library.h
void somefunction1(void);
library.c
#include "library.h"
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
#endif
static unsigned char oneString[LIBRARY_VALUE]; // Also I need to be able
// to use the value to initialize
// static arrays that will be
// modified by somefunction1();
void somefunction1(void)
{
printf("The Library Value is %d\n", LIBRARY_VALUE);
}
What I want to do here, is to be able to compile main.c and having LIBRARY_VALUE‘s value to be used as I defined right after the include in main.c.
How should I use GCC in order to achieve this?
I do need the value to be defined in main.c.
In case I have to change my code, I need a minimum working example code please. So I know clearly how to do this. Thanks.
In C there is no way for different .c files to share a common macro defined in one of the .c files. The tradition is to put it in a .h file, but you say this will not work for you.
You will need a type of "constructor" function that sets up your "static" information at run time. This constructor can be called directly by main.c, or indirectly by having main.c define an extern the library picks up.
I'll throw you some code, but I haven't tried to compile it... I'll leave that as an exercise for the student.
main.c
#include "library.h"
int const library_value = 5;
int main(void)
{
somefunction1();
return 0;
}
library.h
extern int const library_value;
void somefunction1(void);
library.c
#include <assert.h>
#include "library.h"
static unsigned char *oneString;
// destroy any memory from lib_init().
static void lib_clear(void)
{
if ( oneString )
{
free(oneString);
oneString = NULL;
}
}
// initialization - strop the static if the caller is to start it up.
static void lib_init( void )
{
if ( ! oneString ) // (defensive "if" to be sure)
{
assert( library_value > 0 );
oneString = (unsigned char*)malloc( library_value );
atexit( &lib_clear );
}
}
void somefunction1(void)
{
if ( ! oneString ) // if the main() is not calling an the constructor then
lib_init(); // // every method within the library must do so.
printf("The Library Value is %d\n", library_value);
}
The lib_init() and lib_clear() methods could be made externs with a lib_init( int size ) signature to take the size.
Your goal seems to have a single definition referenced multiple places.
There are a limited number of possibilities:
#define in .h
extern defined in main, or somewhere else outside of library.
extern defined in library.
Value passed by caller to library, perhaps an initialization call for the library.
Something defined before #include library.h that is picked up by library.h. I don't like this one.
As alfa says, make it a compile-time definition.
An example of a #define within library.h.
// library.h
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
void somefunction1(void);
#endif
Or, have main define a value defined by the caller and referenced by the library:
// library.h
extern int const library_value; // caller to define in main
void somefunction1(void); // function for caller
// main.c
int const library_value = 5;
int main(void)
{
somefunction1();
return 0;
}
The one I don't like is:
//main.c
#define LIBRARY_VALUE 5
#include "library.h"
//library.h
#ifdef LIBRARY_VALUE
int const library_value = LIBRARY_VALUE; // executable code in .h files is evil
#endif
Some of the reasons I dont' like this is that it is obscure and unconventional, if two or more callers of library.h define LIBRARY_VALUE you will, or at least should, get obscure link time errors. The same applies if LIBRARY_VALUE is not defined by an #include... library.c itself can not define a default value. No, I'd much rather call an initialization function for the library that accepts the constant.
The problem with the way you seem to want this to work, is that the constant gets used when the library is compiled -- you can't use one value when compiling the library and then compile a program with a different value and expect the library's code to magically change to use the new constant. You have some options when it comes to alternatives, though.
You could move the array into the program rather than the library, and give the library a pointer to it, and its size.
Or you could use a dynamically allocated array in the library, and add an initialization function to do the allocation (using the size provided by the program).
Or, you could ditch the library and just compile its code as part of the program -- then you can use a constant defined for the program as long as its done where the (previously) library code will see it.
Recommendation (assuming you want "myarray" visible outside the library):
// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y
#define ARRAY_SIZE 5
extern unsigned char myarray[ARRAY_SIZE]; // Also I need to be able
// to use the value to initialize
// static arrays that will be
// modified by somefunction1();
void somefunction1(void); // function for caller
#endif
/* LIBRARY_H */
Otherwise, if you just want "somefunction1()" and the array size, then declare another function, "array_size ()":
// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y
#define ARRAY_SIZE 5
int array_size (); // library.c will define "myarray" and it will
// define function array_size as "return ARRAY_SIZE;"
void somefunction1(void); // function for caller
#endif
/* LIBRARY_H */
ALSO:
Please remember that "static" has two meanings:
1) Hides visibility of a variable or function name to file scope (the name is "invisible" outside of the source file)
2) allocates space for the object from static storage (instead of the heap (malloc/new) or stack (local variables)).
If you only want the "static storage" part; then you don't need the keyword "static". Just define your variable outside of a function, and you're set :).
Yet another issue is whether you want to make "ARRAY_SIZE" a compile time variable. If so, you should make sure it gets defined EXACTLY ONCE (when library.c is compiled), and is used IN ONLY ONE PLACE (library.c and library.c only). For example:
// library.c
#include "library.h"
#ifndef ARRAY_SIZE
#error ARRAY_SIZE IS UNDEFINED!
#else
static unsigned char myarray[ARRAY_SIZE];
int array_size ()
{
return ARRAY_SIZE;
}
#endif
...
What you are trying to do is not possible because library.c and main.c are compiled separately. You should compile library.c with "gcc -DLIBRARY_VALUE=5 ..." instead.
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;
}