how to share functions in c [duplicate] - 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;
}

Related

Accessing a variable outside a c file

I'm trying to do this code, and I split it up into .c files (lets say file1.c and file2.c) and file1.h file. I'm not allowed to change which parameters I can send to the function, so I need to find another way to "send"/access another variable. I tried to make the variable static in the header file file1.h, and include it in the file2.c. The function in file1.c look something like this:
int function(int *array, int a, int b){
...
...
if(global_variable == 1){
point = array[(a+b)/2];
}else if(global_variable == 0){
point = array[b];
}
and in the file2.c I have a function something like this:
double function2(t_sort_funcp fun, const case_t c, int array_length, result_t *buf, t_generate_array_funcp g_array){
int array[array_length];
switch (c)
{
case first:
global_variable = 1;
g_array(array, array_length);
return debugg(fun, array, array_length);
break;
case second:// Wors case is an inverted sorted array.
global_variable = 0;
g_array(array, array_length);
return debugg(fun, array, array_length);
break;
case third:
global_variable = 1;
g_array(array, array_length);
return debugg(fun, array, array_length);
break;
}
return 0;
}
In the file1.h I have:
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
static int global_variable;
#endif
as you can see, I'm trying to change the global_variable variable in file2.c and use it in file1.c but that does not work, the if-statement in file1.c always executes the code in the else-statement, even if I changed the variable to 1.
NOTE: file2.c always executes before file1.c
Do it the opposite way
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
extern int global_variable;
#endif
In one of the .c files
int global_variable;
Include the .h file in all files which require access to this variable.
static in global scope makes the variable only available in one compilation unit (file).
You can use extern with a cpp conditional.
Below are samples files.
FILE: file1.h
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
#ifdef FILE1_C
int global_variable;
#else
extern int global_variable;
#endif
#endif
FILE: file1.c
// I am file1.c
#define FILE1_C
#include "file1.h"
FILE: file2.c
// I am file2.c
#include "file1.h"
UPDATE:
definitely wrong way. Why this weird ifdef complication –
0___________
No, it's not the wrong way. I do this all the time. The idea is that you have both definitions in the same place/file. If you put the global in a .c file, it's harder to see if you change the type.
Here's a more expanded case:
#ifndef ALGORITHM_H
#define ALGORITHM_H
#include <stdbool.h> // bool
#ifdef FILE1_C
#define EXTRN_FILE1 /**/
#else
#define EXTRN_FILE1 extern
#endif
EXTRN_FILE1 int global_variable;
EXTRN_FILE1 double global_variable_2;
#ifdef FILE1_C
int global_variable_3 = 37;
#else
extern int global_variable_3;
#endif
#endif
And, we may want to put the globals in a different .c file. If we rename FILE1_C to (e.g.) DEFINE_GLOBALS, we can put #define DEFINE_GLOBALS in any .c. If we change our minds later, it's trivial to move the #define from (e.g.) file1.c to file2.c.

Multiple Definition in C header file when using that header in another source file in the same project [duplicate]

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.

How do you define functions in header files?

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.

Include Guard still inserting Global Variables

I have 3 *.c files (file1.c, file2.c and file3.c) and 1 *.h file (file3.h) in a project (Visual Studio).
/*******************************
file3.h
********************************/
#ifndef FILE3_H
#define FILE3_H
int gintVariable = 400;
#endif
/*******************************
file1.c
********************************/
#include "file3.h"
#include <stdio.h>
#include <conio.h>
int modifyGlobalVariable(void);
void printGlobalVariable(void);
int main(void)
{
modifyGlobalVariable();
printGlobalVariable();
printf("Global variable: %d\n", gintVariable++);
getch();
return 0;
}
/*******************************
file2.c
********************************/
#include "file3.h"
int modifyGlobalVariable(void)
{
return gintVariable++;
}
/*******************************
file3.c
********************************/
#include "file3.h"
#include <stdio.h>
void printGlobalVariable(void)
{
printf("Global: %d\n", gintVariable++);
}
When I build the solution in VS, it is giving error as "_gintVariable already defined in file1.obj".
I did check in the pre-processor output, the gintVariable is included in all the *.c files even though I have included include guards.
What mistake I am doing?
You should use 'extern' while declaring a global variable in header file.
Define it in any one of *.c file.
This should fix the issue.
For more on header files, read
How do I use extern to share variables between source files?
Including guards prevents multiple inclusion (or, more precisely, multiple compilation of the .h file content) in a single translation unit.
It is useful against this problem:
/* glob.h */
#ifndef H_GLOB
#define H_GLOB
struct s { int i; };
#endif
/* f.h */
#ifndef H_F
#define H_F
#include "glob.h"
struct s f(void);
#endif
/* g.h */
#ifndef H_G
#define H_G
#include "glob.h"
struct s g(void);
#endif
/* c.c */
#include "f.h" /* includes "glob.h" */
#include "g.h" /* includes "glob.h" */
void c(void) {
struct s s1 = f();
struct s s2 = g();
}
The inclusions is like a diamond:
glob.h
/ \
f.h g.h
\ /
c.c

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