Include nested duplicate file inclusion condition Compilation

Source: Internet
Author: User

Compiling a C program involves many steps. Step 1 is called preprocessing. The C Preprocessor performs some text operations before source code compilation. Its main tasks include deleting comments, inserting File Content contained by the # include command, defining and replacing symbols defined by the # define command.

Both C and C ++ use the # include command to include the header file. # Include supports library files and local files.

When writing a small program, we will not encounter this nested inclusion problem in most cases. However, when you try to use a multi-head file, you may encounter a "conflict with the '**' type" error. In the end, you cannot combine multiple heads into one file. Some may wonder why the header file of the function library can be included multiple times, but I cannot?

Let's assume that the following is a simple nested header file inclusion:

A. H file has a struct Declaration: mystruct

B. H uses # include "A. H" to include a. h and defines a function print_ B ()

C. H uses # include "A. H" to include a. h and defines a function print_c ()

D. C contains both B. H and C. H.

Link example:

A.h

#include<stdlib.h>#include<stdio.h>#include<string.h>typedef struct mystruct{    char a[10];}mystruct;

B. H

#include "a.h"void print_b(){    mystruct a;    strcpy(a.a,"a.h");    printf("this is in b.h %s\n",a.a);}

C. h

#include "a.h"void print_c(){    mystruct c;    strcpy(c.a,"a.h");    printf("this is in c.h %s\n",c.a);}

D. c

#include "b.h"#include "c.h"int main(){    printf("this is in main\n");    print_b();    print_c();    return 0;}

Gcc a. h B. H C. H D. C-o d. o cannot be compiled successfully.

# Gcc. h B. h c. h d. c-o d. oin file encoded ded from C. h: 1: 0, from D. c: 2:. h: 4: 16: Error: 'struct mystruct 'redefinition. h: 4: 16: Note:. h: 6: 2: Error: conflict with 'mystruct 'type. h: 6: 2: Note: the previous statement of 'mystruct 'Here

The reason is that during preprocessing, the content of the entire header file is read, and the content of A. H is repeatedly included twice. A type conflict occurs.

When compiling a program, you can use Conditional compilation to select whether part (or all) of the code is properly compiled or completely ignored. Here, it can be useful.

Replace a.h with the following content:

A.h

/*a.h*/#include<stdlib.h>#include<stdio.h>#include<string.h>#ifndef _a_H#define _a_H 1typedef struct mystruct{    char a[10];}mystruct;#endif

Gcc a. h B. H C. H D. C-o d. o

./D. o

this is in mainthis is in b.h a.hthis is in c.h a.h

No type conflict is found.

In fact, Conditional compilation is used in a. h (this is also the reason why the header file of the function library can be included multiple times ).

# Ifndef _ a_h

# DEFINE _ a_h 1

/* This is the original content of your header file */

# Endif

This eliminates the risk of repeated inclusion. When the first file is contained, it is processed normally. the symbol _ a_h (which can be defined by yourself) is defined as 1 (this is not necessary, you can also directly write it as # DEFINE _ a_h ). If the header file is included again, It is compiled using conditions. It indicates that the content containing (between # iinfdef... # endif) will be ignored.

The example here is only for a clearer view of the function of Conditional compilation, so only. H is used. In fact, if all our header files are compiled using the above Conditional compilation method, the risk of multiple inclusion can be eliminated. When others use your header file, they may not know how many other files it contains. (It is best to avoid multiple inclusion times, because preprocessing will still read the entire header file, even if it has been ignored)

Of course, Conditional compilation is not only used here, for example, it is often used when debugging is required for programming. Some debugs are required in the programming stage. Conditional compilation is very useful when there is no need to output them during delivery. (Below are my frequently used ones. Note that this is the # ifdef)

/*#define DEBUG_MIGRATION*/#ifdef DEBUG_MIGRATION#ifdef CONFIG_LINUX#include <sys/syscall.h>#define DPRINTF(fmt, ...)                                               \    do {                                                                \        printf("%d:%ld %s:%d: " fmt, getpid(), syscall(SYS_gettid),     \               __func__, __LINE__, ## __VA_ARGS__);                     \    } while (0)#else#define DPRINTF(fmt, ...)                                               \    do {                                                                \        printf("%s:%d: " fmt, __func__, __LINE__, ## __VA_ARGS__);      \    } while (0)#endif#else#define DPRINTF(fmt, ...)       do { } while (0)#endif

When debugging is output, # define debug_migration is required. If debugging is not needed, the debugging information of the entire file is not output.

The following is an example:

DPRINTF("flushed %zu of %zu byte(s)\n", offset, s->buffer_size);

Dprintf is used to output debug.

The common syntax is as follows:

#if constant-expression      statements#elseif constant-expression      statements2#else      other statements#endif

Commonly used judgments are defined

# Ifndef something/* something is not defined */

# Ifdef something/* something already defined */

Refer:

Pointers on C, kenth A. reek

Qemu/KVM source code

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.