[Original] research on the Inclusion sequence of C ++ header files

Source: Internet
Author: User
Tags acos

 

Author: Zhu Jincan

Source: http://blog.csdn.net/clever101

 

I. Views in Google C ++ programming style guide

 

The company is implementing code specifications, and the leaders propose to basically use Google C ++ programming style guide. Google C ++ programming style guide contains the following sequence of header files:

 

Names and order of orders des

Link between use standard order for readability and to avoid hidden dependencies: C library, C ++ library, other libraries '. H, your project's. h.

All of a project's header files shoshould belisted as descendants of the project's source directory without use of unixdirectory shortcuts. (the current directory) or .. (the parent directory ). forexample, Google-awesome-Project/src/base/logging. h shocould be encoded

 

# Include "base/logging. H"

In Dir/Foo. cc or DIR/foo_test.cc, whosemain purpose is to implement or test the stuff in dir2/foo2.h, order yourincludes as follows:

 

Dir2/foo2.h (Preferred location-seedetails below ).

C system files.

C ++ system files.

Other libraries '. H files.

Your project's. H files.

The preferred ordering has CES hiddendependencies. we want every header file to be compilable on its own. theeasiest way to achieve this is to make sure that every one of them is the first. h file # sorted ded in some. cc.

 

DIR/Foo. CC and dir2/foo2.h are often in thesame directory (e.g. Base/basictypes_test.cc and base/basictypes. h), but can bein different directories too.

 

Within each section it is nice to order theincludes alphabetically.

 

For example, the primary des ingoogle-awesome-Project/src/Foo/Internal/fooserver. CC might look like this:

 

 
# Include "foo/public/fooserver. H "// Preferred location. # include <sys/types. h> # include <unistd. h> # include 

Here I will talk about my understanding of the above (if not, please correct me ):

1. To enhance readability and avoid implicit dependency, use the following sequence: header files of the C standard library, C ++ standard library, other libraries, and header files of your own project. However, the first header file to be included here is the preferred header file. For example, the. cpp file should first contain a. h. The preferred header file is to reduce hidden dependencies and ensure that the header file matches the implemented file. For example, if you have a CC file (the CPP file on the Linux platform is suffixed with CC) That is Google-awesome-Project/src/Foo/Internal/fooserver. CC, the sequence of header files contained in it is as follows:

 
# Include "foo/public/fooserver. H "// Preferred location. # include <sys/types. h> # include <unistd. h> # include 


 

 

2. When the header file is included, add the folder name of the project where the header file is located, that is, if you have such a project base with a logging. h in it, the header file containing the external file should be written as follows:

# Include "base/logging. H" instead of # include "logging. H"

 

What we see is the hidden purpose behind the principles proposed in the Google C ++ programming style guide:

1. To reduce the hidden dependency and match the header file with the implemented file, you should first include its preferences (that is, the corresponding header file ).

 

2. In addition to preferences, the general and special principles are followed. However, I think the sequence of Google C ++ programming style guide is as follows: the header files of the C standard library, C ++ standard library, and other libraries, and the header files of your own project are missing the first one: header files of the operating system level, for example, sys/types. H is not included in the C standard library, but the SDK provided by the Linux operating system. Therefore, I think the more accurate statement should be: OS SDK. h, C standard library, C ++ standard library, header files of other libraries, and header files of your own project.

 

3. The reason for listing the project directory where the header file is located should be that the namespace is the same, in order to distinguish the file names that are accidentally generated.

 

 

Ii. different points of view in C ++ programming thoughts

Unlike Google C ++ programming style guide, C ++ programming ideology advocates a different rule. The C ++ programming ideology p432 mentioned:

The sequence in which header files are contained is from "most special to most general ". This means that any header file in the local directory is first included. Then all our own "tool" header files, followed by third-party library header files, followed by standard C ++ library header files and C library header files.

For more information, see johnlakos in large scalec ++ softwre design.ProgramA passage in design:

 

Ensure that the components of the. h file are not parsed by itself (PARSE), which can avoid potential usage errors. It is because of the lack of explicit declarations or definitions provided by the parsing itself. In. the first line of the C file contains. the H file ensures that all the internal information blocks that are important to the physical interface of the component are located. h. c file ).

 

If the sequence of header files is "from the most special to the most general", if our header files are not parsed by itself. We will immediately find it to prevent trouble.

 

3. My Experiments

 

Which of the following has a good order of inclusion? I used VS 2005 to compile a console test project testinc, which contains several files.

 

Mymath. hCodeAs follows:

 
# Pragma once # pragma oncedouble ACOs (double num );


The code for mymath. cpp is as follows:

 
Double ACOs (double num) {return 1.0 ;}


The code for testinc. cpp is as follows:

 
# Include "stdafx. H "# include" testinc. H "# include <stdio. h> # include <math. h> int _ tmain (INT argc, _ tchar * argv []) {double A = ACOs (0.5); Return 0 ;}


The result is incorrect:

1> C: \ Program Files \ microsoft visualstudio 8 \ Vc \ include \ math. H (107): Error c2732: Conflicts between the link specification and the early specification of "ACOs"

1> C: \ Program Files \ Microsoft Visual Studio 8 \ Vc \ include \ math. H (107): see the "ACOs" statement.

 

Then I changed the header file inclusion sequence of testinc. cpp:

 
# Include "stdafx. H" # include <stdio. h> # include <math. h> # include "testinc. H"


 

The compilation is successful. During debugging and running, the main function is called or the C standard library function ACOs. It seems that the order of function calls is in the order of header file inclusion, that is, my custom ACOs function is overwritten (if testinc. h contains inline functions, which are called first ).

 

From this small experiment, I come to the following conclusions: the sequence of header files included in Google C ++ programming style guide and C ++ programming ideas have their own advantages, google C ++ programming style guide should be able to greatly reduce the dependency on hidden header files, c ++ programming ideology makes it easy for you to know whether the interface you have defined conflicts with the system library and third-party library.

 

4. Pre-compilation in header files

 

In the Visual Studio environment, we found that almost every CPP file must contain the stdafx. h file and put it at the beginning. Otherwise, an error will occur. Why?


Originally, Visual Studio used a pre-compilation mechanism. To understand the pre-compilation mechanism, first introduce the pre-compilation header. The so-called pre-compilation header is to pre-compile the part of the code in a project and put it in a file (usually. PCH Extension). This file is called the precompiled header file. The pre-compiled code can be any C/C ++ code, or even an inline function, however, it must be stable and won't be changed frequently during project development. If the code is modified, re-compile the pre-compiled header file. Note that it takes a lot of time to generate a pre-compiled header file. At the same time, you must note that the pre-compiled header file is usually large, usually 6-7 M. Clear unused pre-compiled header files in time.

 

You may ask: The current compiler has the time stamp function. When the compiler compiles the entire project, it only compiles the modified files, instead of compiling files that have not been modified since the previous compilation. So why do we need to pre-compile the header file? Here, we know that the compiler is compiled in files. After a file is modified, it will re-compile the entire file. Of course, all the header files contained in this file (. eg macro, Preprocessor) must be processed again. The pre-compiled header file of VC stores this part of information. To avoid re-processing these header files every time.

 

According to the above introduction, the role of pre-compiled header files is of course to improve the cost efficiency. With it, you do not need to compile the code that does not need to be changed frequently every time. Of course, the compilation performance is improved.

 

To use the pre-compiled header, we must specify a header file, which contains code that we will not change frequently and other header files. Then we use this header file to generate a pre-compiled header file (. PCH file) We all know stdafx. h. Many people think that this is a system-level file provided by VC, a header file carried by the compiler. Actually not. This file can be of any name. We will examine a typical pre-compiled header file of the MFC dialog based program generated by Appwizard. (Because Appwizard specifies how to use the pre-compiled header file. The default value is stdafx. H, which is the name of VC ). We will find that this header file contains the following header files:

# Include <afxwin. h> // MFC core and standard components # include <afxext. h> // MFC extensions # include <afxdisp. h> // MFC automation classes # include <afxdtctl. h> // MFC support for Internet Explorer 4 common controls # include <afxcen. h>


 

These are the necessary header files used by MFC. Of course, we are unlikely to modify these header files in our project, so they are stable.

 

Then how do we specify it to generate the pre-compiled header file. We know that a header file cannot be compiled. Therefore, we need a CPP file to generate the. PCH file. The default value of this file is stdafx. cpp. There is only one code in this file: # include "stdafx. H ". The reason is, of course, we only need to compile it-that is to say, it only needs its. cpp extension. We can use the/YC compilation switch to specify stdafx. cpp to generate a. PCH file, and use the/FP compilation switch to specify the name of the generated PCH file. Open the project-> setting-> C/C ++ dialog box. Point category to the precompiled header. Select the entire project in the Tree View on the left. Project Options (the white place in the lower right corner) shows/FP "Debug/PCH. PCH ", which is generated by the specified. the name of the PCH file. The default value is usually <Project Name>. PCH. Then, select stdafx. cpp in the Tree View on the left, and the original project option becomes the source file option (originally a project, now a file, of course changed ). Here we can see the/YC switch. The function of/YC is to specify this file to create a PCH file. The file name after/YC is the header file that contains stable code. Only one file in a project can have the YC switch. VC compiles stdafx. cpp into an OBJ file and a PCH file based on this option.

In this way, we have set the pre-compiled header file. That is to say, we can use the pre-compiled header function. Note:

 

1) if/Yu is used, that is, pre-compilation is used. the beginning of the CPP file, including the file that you specified to generate PCH. h file (default is stdafx. h) otherwise there will be problems. If you do not include this file, tell you unexpected file end.

 

2) If you accidentally lose the PCH file, you only need to let the compiler generate a PCH File Based on the above analysis. That is to say, you can recompile stdafx. cpp (that is, the CPP file of the specified/YC.

Is there such a pre-compilation mechanism on Linux? If so, how is it implemented? In Linux, the GCC compiler also implements the pre-compilation mechanism. Here we use the open-source ide codeblocks (codeblocks has built-in GCC compiler) project as an example to illustrate the implementation of the Linux platform:

 

 
Use codeblocks to create a C ++ project, create a new my_pch.h, and enter the following code:
/*************************************** * ************************* Name: my_pch.h * purpose: header to create pre-compiled header (PCH) * Author: () * created: 2010-10-26 * copyright: () * license: * usage: project construction option --> other options --> fill in the following two lines-winvalid-PCH-include my_pch.h ******************** **************************************** **/# ifndef my_pch_h_included # define my_pch_h_included // put here all your rarely-changing header files # include <iostream> # include <string> # endif


 
Then, enter the following two lines in the Project Build option --> other options --> winvalid-PCH-include my_pch.h.
 
You can enable the precompiled file header. Then main. cpp can be compiled without the need to include the header file,
Int main () {using namespace STD; cout <"Hello world! "<Endl; return 0 ;}


Even if the code above writes the following line, it does not work:

 
# Include <iostream>


 

References:

 

1. compiler Processing

Http://blog.donews.com/xzwenlan/archive/2004/12/23/211668.aspx

 

2. googlec ++ Style Guide

Http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Names_and_Order_of_Includes

 

3. c ++ programming thoughts

 

4. Pre-compile function of VC ++

 

Http://www.neu.edu.cn/cxsj/pointchart/c11/VC++%282%29.html

 









Author: clever101 posted on 21:18:28 Original article link Read: 11518 comments: 23 views comments

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.