Function declared twice in C header file - c

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.

Related

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;
}

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.

undeclared variable. [ issue with headers ]

I have headers in my microcontroller program
#ifndef __IRQ_HANDLER__
#define __IRQ_HANDLER__
#ifdef __cplusplus
volatile tU32 ticks = 0; // <- with that variable i have problem
extern "C" {
#endif
void interrupt2(void);
#ifdef __cplusplus
}
#endif
#endif //__IRQ_HANDLER__
Then file.c
#include <lpc2xxx.h>
#include "interrupt.h"
void interrupt2(void) {
ticks++;
T1IR = 0xff;
VICVectAddr = 0x00;
}
Every time when i'm trying to use variable ticks. I got an error :
'ticks' undeclared ( first use in this function ).
Have you any clue what might be wrong ?
Greetings !
Note: in the following code example, I stripped all the unrelated statements
1) do not declare variables in a header file. if necessary, use the 'extern' modifier in the header file.
2) Declare the variable in a source file, like main.c
3) any symbol name beginning with underscore+capital letter Or two underscores are 'reserved' for the system. Therefore strongly suggest replacing all instances of __IRQ_HANDLER__ with the (typical) INTERRUPT_H
an example code:
file: interrupt.h
#ifndef INTERRUPT_H
#define INTERRUPT_H
#ifdef __cplusplus
extern "C" {
#endif
extern volatile unsigned int ticks;
void interrupt2(void);
#ifdef __cplusplus
}
#endif
#endif // INTERRUPT_H
file: interruptHandler.c
#include "interrupt.h"
volatile unsigned int ticks = 0;
void interrupt2(void)
{
ticks++;
}
There needs to be a third file that declares the variable: ticks
and if declared in the file global space,
it will automatically be initialized to 0
It is necessary to also treat the code in the third file that accesses the ticks variable as a 'critical section. Probably by:
disable the interrupts
copying ticks to a local variable
enable the interrupts

doxygen can't generate extern api in c

I want to document an extern API in an header file as below
// bar.h
#ifdef __cplusplus
extern "C" {
#endif
/**
* \memberof bar
* This is foo
*/
extern int foo();
#define JUNK_A DONT_DOC_IT
#define JUNK_B DONT_DOC_IT
#ifdef __cplusplus
}
#endif
Function foo() is defined is somewhere in archive file and "bar.h" is exposed as user API and I want to document it. But doxygen cannot generate it.
I don't want to enable EXTRACT_ALL because there are some other things I don't want to document it.
As sample code shows I've tried \memberof but it's not work. Could someone can help me?
As hint from #rveerd, I complete the answer. At first it needs a \file commands to document global objects. At this step all objects are documented include those we don't want to document. So we need discard parts we don't need via adding \cond HIDDEN_SYMBOLS. The sample code is as below:
/** #file test.h */
#ifdef __cplusplus
extern "C" {
#endif
/**
* #brief This is foo
*/
extern int foo();
/** #cond HIDDEN_SYMBOLS */
#define JUNK_A DONT_DOC_IT
#define JUNK_B DONT_DOC_IT
/** #endcond */
#ifdef __cplusplus
}
#endif
You at least need to document the file itself with \file for anything to be generated. Not sure if this is enough to generate documentation for the extern function, though.

How to create interface file for SWIG

I have the following header files:
gaiageo.h
which is defined as
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* stdio.h included for FILE objects. */
#include <stdio.h>
#ifdef DLL_EXPORT
#define GAIAGEO_DECLARE __declspec(dllexport)
#else
#define GAIAGEO_DECLARE extern
#endif
#endif
#ifndef _GAIAGEO_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GAIAGEO_H
#endif
#include "gg_const.h"
#include "gg_structs.h"
#include "gg_core.h"
#include "gg_mbr.h"
#include "gg_formats.h"
#include "gg_dynamic.h"
#include "gg_advanced.h"
#endif /* _GAIAGEO_H */
The included header files are riddled with GAIAGEO_DECLARE, for
instance gg_formats.h (which is very typical of the included headers) has the following:
/**
\file gg_formats.h
Geometry handling functions: formats
*/
#ifndef _GG_FORMATS_H
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#define _GG_FORMATS_H
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/* function prototypes */
/**
Test CPU endianness
\return 0 if big-endian: any other value if little-endian
*/
GAIAGEO_DECLARE int gaiaEndianArch (void);
/**
Import an INT-16 value in endian-aware fashion
\param p endian-dependent representation (input buffer).
\param little_endian 0 if the input buffer is big-endian: any other value
for little-endian.
\param little_endian_arch the value returned by gaiaEndianArch()
\return the internal SHORT value
\sa gaiaEndianArch, gaiaExport16
\note you are expected to pass an input buffer corresponding to an
allocation size of (at least) 2 bytes.
*/
GAIAGEO_DECLARE short gaiaImport16 (const unsigned char *p,
int little_endian,
int little_endian_arch);
#ifdef __cplusplus
}
#endif
#endif /* _GG_FORMATS_H */
This is my first attempt at creating interface files and would like some help, online documentation is confusing me?
Should I be creating an interface file for each header and how should I create the interface for the encompassing gaiageo.h?
This should get you started, but it is difficult to know exactly what you'll need.
%include <windows.i> makes SWIG handle Window-isms like __declspec(dllexport).
SWIG does not recurse include files by default, so include the ones you need SWIG to process. There is a switch to recurse, but then it would process stdio.h.
%module gaiageo
%{
#include "gaiageo.h"
%}
%include <windows.i>
%include "gaiageo.h"
%include "gg_const.h"
%include "gg_structs.h"
%include "gg_core.h"
%include "gg_mbr.h"
%include "gg_formats.h"
%include "gg_dynamic.h"
%include "gg_advanced.h"
Save that as a gaiageo.i file and run something like:
swig -c++ -<target_language> gaiageo.i

Resources