How does inclusion of header file happen?

穿精又带淫゛_ 提交于 2019-12-01 14:46:33

You should start by putting an inclusion lock in all your .h files (this is called an include guard):

#ifndef ONE_H
#define ONE_H

//rest of header

#endif //ONE_H

That way you can include it multiple times.

Second:

typedef struct my1 { int a; .. .. }my_t;

You need a typedef in C (not in C++)

The headers are included in the order of inclusion.

If you compile a file abc.c which starts with:

#include "a.h"
#include "b.h"

then a.h will be included first, then b.h.

You could think of it, as if you paste the code in the file. It is included at that point.

It's like the folks said before.

I just want to add that sometimes even #ifdef won't help you.

//file1.h
#ifndef F1
#define F1

#include "file2.h"

struct file1st {
  struct file2st *ptr;
};

#endif

//file2.h

#ifndef F2
#define F2

#include "file1.h"

struct file2st {
   struct file1st *ptr;
};

#endif

//main.c

#include "file1.h"
#include "file2.h"

/*
This will give you an error of **struct file1st not defined**
Let's see why: 

1) file1.h is included
2) file1.h includes file2.h before it declares anything
3) the definition of struct file2st occurs and it uses struct file1st which isn't declared yet
*/

int main(int argc, char* argv[]){
  struct file1st st1;
  struct file2st st2;

  return 0;
}

The way to work this out is:

//file1.h
    #ifndef F1
    #define F1

    struct file2st;//just declare, it will be defined later. 

    struct file1st {
      struct file2st *ptr; // ok, compiler KNOWS the size of struct file2st*(pointer)
      struct file2st file2Var;// NOT ok, compiler doesn't know sizeof(struct file2st)
    };

    #endif

    //file2.h

    #ifndef F2
    #define F2

    #include "file1.h"

    struct file2st {
       struct file1st *ptr;
    };

    #endif

Header files are included in the order of include directives. Once the compiler sees an include directive it opens the file to include and simply inserts all of its contents into the including file.

If the included file has include directives inside, the same is done for them. This process continues until all of the include directives have been processed.

Only after that the compilation is started.

That's why if any file is included more than once (A included B and C; both B and C include D for example) you'll often see compiler complaining about redefinitons. To resolve this add inclusion locks (aka include guards) - the ifdef directives.

//file Header1
#ifndef Header1Guard
   #define Header1Guard
// all the header text here
#endif

I second the guard suggestion.

I religiously use the following header template:

#ifndef HELLOWORLD_H_
#define HELLOWORLD_H_

// Header stuff here.

#endif // HELLOWORLD_H_

When the compiler see's an #include, it simply replaces that line with the contents of the header file (minus any processed directives in the header). So, that means you can include the file in as many places as you like without risking recursive includes.

Every header file is included in every translation unit (source file) in which there is an include directive for it. This is intended, and will happen even with inclusion guards -- every translation unit that uses your struct needs to know how that struct is defined so that it can be laid out in memory the same way throughout all the translation units of your app. The inclusion guards just prevent it from being included multiple times within one translation unit. Include files will be included in the order you include them within that translation unit (and they'll be recursively included if include files include other files... as others have said). The order of translation units being compiled is up to you (or your IDE) to specify to the compiler. It shouldn't matter what that order is, however, since every translation unit is completely independent until it gets to the linking phase of the build process.

It's been a while since I worked with C, but I think what you want to do is forward define my1.

In 2.h, try putting this near the top:

struct my1;

Sorry, I can't answer your other two questions.

// Header1.h
typedef struct tagHeader1
{
} Header1;

// Header2.h

struct Header1;

// Header2.c

#include "Header1.h"

Note: This only works for pointers (and in c++, references). If you have a reference to a complete object, the compiler will need to know about it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!