The C language often appears in the file duplicate contains and causes the global variable to duplicate the definition, below an example illustrates
-----Makefile
CC = gcc
objs = main.o errhandle.o strcopy.o
cflags =-wall-std=c99
main: ${objs} # or $ (OBJS), ${OBJS} i s shell style
${cc} ${cflags}-o $@ ${objs}
main.o:main.c errhandle.h strcopy.h
${cc} ${cflags}-C main.c
errhandle.o:errhandle.c errhandle.h
${CC} ${cflags}-C errhandle.c strcopy.o:strcopy.c strcopy.h
Errhandle.h
${CC} ${cflags}-C strcopy.c clean
:
rm-f main *.O
-----MAIN.C
#include <stdio.h>
#include "errhandle.h"
#include "strcopy.h"
#define DESTSIZE
int Main (int argc, char *argv[])
{
char dest[destsize];
Char *src = "1234567890";
if (Strcopy (dest, destsize, SRC)!= NULL)
{
printf ("%s\n", dest);
}
else
{
printerr ();
}
if (Strcopy (dest, destsize, NULL)!= null)
{
printf ("%s\n", dest);
}
else
{
printerr ();
}
return 0;
}
-----errhandle.h
/* ERROR handle
/#ifndef _errhandle_h
#define _ERRHANDLE_H /To avoid duplicate (multiple) Inclusion or declare (definition) of the header file
#ifdef __cplusplus
extern "C" {
#endif
extern int err Code;
#define Err_short 1/ * The dest string is too short */
#define ERR_SRCNULL 2/* The src string po Inter is null
/#define ERR_DESTNULL 3 /* dest string pointer is null *
/extern void Printerr (); c19/> #ifdef __cplusplus/ * extern "C" */
}
#endif
#endif/ * _errhandle_h *
-----errhandle.c
#include <stdio.h>
#include "errhandle.h"
int errcode;
void Printerr ()
{
if (Err_short = = Errcode)
{
printf ("The dest string is too short\n")
;
else if (err_srcnull = = Errcode)
{
printf ("The SRC string pointer is null\n");
}
else if (err_destnull = = Errcode)
{
printf ("The Dest string pointer is null\n");
}
-----strcopy.h
#ifndef _strcopy_h
#define _STRCOPY_H //To avoid duplicate (multiple) inclusion or declare (definition) of hea Der file
#ifdef __cplusplus
extern "C" {
#endif
extern char *strcopy (char *dest, unsigned int dest_len, c Onst char *src);
#ifdef __cplusplus/ * extern "C" * * *
#endif
#endif/ * _strcopy_h * *
-----STRCOPY.C
#include <string.h>
#include "errhandle.h"
#include "strcopy.h"
Char *strcopy (char *dest, unsigned int dest_len, const char *src)
{
char *dest_p = NULL;
int i;
if (dest = = NULL)
{
errcode = err_destnull;
return NULL;
}
if (src = NULL)
{
errcode = err_srcnull;
return NULL;
}
if (Dest_len < strlen (SRC) + 1)
{
errcode = Err_short;
return NULL;
}
for (i = 0, dest_p = dest Src[i]!= '; i++, dest_p++)
{
*dest_p = Src[i];
}
*dest_p = ' n ';
return dest;
}
In this case, STRCOPY.C and errhandle.c have to use the Errcode global variable, and other dependencies see the above code
Description
1, the following way to prevent the header file repeat contains or defined:
#ifndef _errhandle_h
#define _ERRHANDLE_H //To avoid duplicate (multiple) inclusion or declare (definition) The header file ...
#endif/ * _errhandle_h * *
2. The description of extern "C" can be seen here: about extern "C", http://effective-c.googlecode.com/files/effective-c.pdf
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus/ * extern "C" */
}
#endif
3. Declare an extern int errcode in the errhandle.h, and declare int errcode in errhandle.c to resolve Errcode definition caused by duplicate inclusion. This usage can be seen in the errno.h and errno.c of standard C library.
--------------------------------------------------------------------------------------------------------------- -----------------------
Here is another way to refer to the article http://www.4ucode.com/Study/Topic/951741
Modify only Errhandle.h and errhandle.c 2 files
-----errhandle.h
/* ERROR handle
/#ifndef _errhandle_h
#define _ERRHANDLE_H /To avoid duplicate (multiple) Inclusion or declare (definition) of the header file
#ifdef __cplusplus
extern "C" {
#endif
#ifdef Errhandle_globals
#define ERRHANDLE_EXT
#else
#define Errhandle_ext extern
#endif
errhandle_ext int errcode;
#define Err_short 1/ * The dest string is too short */
#define ERR_SRCNULL 2/* The src string po Inter is null
/#define ERR_DESTNULL 3 /* dest string pointer is null *
/extern void Printerr (); c25/> #ifdef __cplusplus/ * extern "C" */
}
#endif
#endif/ * _errhandle_h *
-----errhandle.c
#define ERRHANDLE_GLOBALS/ * This statement must be in front of the #include "errhandle.h" * *
#include <stdio.h>
#include " Errhandle.h "
void Printerr ()
{
if (Err_short = = Errcode)
{
printf (" The dest string is too short\n ") ;
}
else if (err_srcnull = = Errcode)
{
printf ("The SRC string pointer is null\n");
}
else if (err_destnull = = Errcode)
{
printf ("The Dest string pointer is null\n");
}
Description
What is changed in Errhandle.h:
#ifdef errhandle_globals
#define ERRHANDLE_EXT
#else
#define Errhandle_ext extern
#endif
Errhandle_ext int Errcode;
The int errcode is removed from the errhandle.c; The statement, added:
#define ERRHANDLE_GLOBALS/ * This statement must be in front of the #include "errhandle.h" * *
The principle of this method is simple:
Errhandle_globals-defined file: Errhandle_ext int errcode; = = int Errcode;
Errhandle_globals file not defined: Errhandle_ext int errcode; = = extern int Errcode;
In this way, there is only an int errcode; Declaration in errhandle.c, the other files are extern int errcode;
In fact, after preprocessing, it's the same as the first method.