Preventing redefinition of C-potential rules

Source: Internet
Author: User

In C program compilation, errors similar to xxx redefinition often occur. Apart from naming conflicts (naming pollution and static) between modules, most of the problems are related to header file management. Header file management for large C projects is very troublesome: C source files often contain many header files, and the header files contain other header files to form complex nested inclusion. C does not strictly limit the functional boundaries between the source files and header files, both of them can contain entity definitions such as global variables and functions. This may cause Repeated inclusion and expansion of the type or object definition, and cause the compiler to throw a redefinition error.

The solution to the redefinition problem is divided into three parts. Most people only know one of them but do not know its two and three:

First, use Conditional compilation(Header file guard) prevent repeated inclusion of header files

Assume that the source file test. c contains. h and B. h Two header files, and. h and B. h contains another header file x. h (common), then x. h will be tested. c Two include, if x. h defines a struct, such:

Typedef struct

{

......

} TEST

After preprocessing (see the C compilation process), test. c contains two struct TEST definitions, and the compiler reports a redefinition error. A clever way is to apply the following header file template (also known as header file guard ):

# Ifndef _ HDRNAME_H // _ HDRNAME_H names by header file name to prevent conflict of the same name

# Define _ HDRNAME_H

...... (Content of header file)

# Endif

When the first file is included, _ HDRNAME_H has not been define yet. # If the ifndef condition is met, the Preprocessor enters between # ifndef and # endif. _ HDRNAME_H is officially define, And the header file content is also processed. When it is contained again, because _ HDRNAME_H has been defined, the # ifndef at the beginning is no longer satisfied, and the header file content is directly ignored. This prevents type redefinition errors caused by repeated header file inclusion. This is basically a standard of C.

Second, define global variables and functions in the C source file. do not define them in the header file.

# Ifndef prevents duplicate header file inclusionType redefinition in the compilation phaseErrors, but cannot prevent global variables and function definitions in the header file.Link stage real weight DefinitionError. For example:

/************ Main. c ************/

# Include "test. h"

Void main ()

{

Test1 ();

Test2 ();

}

/********** Test. h **********/

# Ifndef _ TEST_H _

# Define _ TEST_H _

Char str1 [] = "char1 ";

Char str2 [] = "char2 ";

# Endif

/********* Test1.c ***********/

# Include "test. h"

Extern char str1 [];

Void test1 ()

{

Printf (str1 );

}

/********* Test2.c ************/

# Include "test. h"

Extern char str2 [];

Void test2 ()

{

Printf (str2 );

}

In the above situation, some compilers report warn, and some may have str1 and str2 redefinition errors. People with unclear concepts may ask: test. h used # ifndef prevents re-inclusion. Why is there a re-definition?

This is actually another problem. The root cause of the error is that test. h contains entity elements such as variables/functions that occupy memory, not just virtual types such as define/struct/union. Although # ifndef is used to prevent test. h. h, the pre-processor will put test. h is appended to the beginning of two source files, which is equivalent to repeating the definition of two global variables str1 and str2 in test1.c and test2.c. After the link is compiled, linker will find that both test1.obj and test2.obj have the str1 and str2 symbols, so an error is reported, which is the same as the C naming conflict.

The solution is to define the global variables in the. c file, and then create a header file containing all the global variables extern declaration. All other. c files that use these variables must contain this header file. As follows:

/***** Main. c *****/

# Include "test. h"

Char str1 [] = "char1 ";

Char str2 [] = "char2 ";

Void main ()

{

Test1 ();

Test2 ();

}

/***** Test. h *****/

# Ifndef _ TEST_H _

# Define _ TEST_H _

Extern char str1 [];

Extern char str2 [];

# Endif

/***** Test1.c *****/

# Include "test. h"

Void test1 () {printf (str1 );}

/***** Test2.c *****/

# Include "test. h"

Void test2 () {printf (str2 );}

Define the function in the header file. The error is similar to the cause. Therefore, the header file can contain the type definition and object Declaration, and should not contain the object definition. In addition, the omission of typedef may cause similar redefinition problems:

Typedef struct {

....

} TEST_S;

If typedef before struct is omitted, TEST_S becomes an unsung struct variable instead of the original custom type, and an error occurs when it is put in the header file.

Third, use wrapper to reasonably use the scope

Sometimes the source file must contain two system or SDK header files with the same name. If the APIs of the two third-party libraries that contain the same name have the same custom type, an error may occur. It is generally inconvenient to modify the header file of a third-party SDK. To solve the conflict, you can use wrapper to encapsulate a library. That is, the programmer encapsulates a new set of APIs in a separate. c file. This API directly calls and maps the functions in the encapsulated object lib. In this way, the. h file corresponding to the original lib is only contained in the wrapper. c file, and the new. h file of the external API can be removed from conflicting definitions with other systems.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.