结构定义是否应该在。h或。c文件中?

时间:2021-08-10 11:10:55

I've seen both full definitions of structs in headers and just declarations—is there any advantage to one method over the other?

我已经看到了在header中对struct的完整定义,并且仅仅是声明—在另一个方法上有什么优势吗?

If it makes a difference, I usually typedef a struct like so in the .h

如果它有区别,我通常在。h中定义一个结构。

typedef struct s s_t;

Edit

To be clear, the options are declaration in the header file and definition in the class, or both declaration and definition in the header file. Both should result in the same usability, even if one is by linkage, shouldn't they?

要清楚,选项是在头文件中声明,在类中定义,或者在头文件中声明和定义。两者都应该得到相同的可用性,即使一个是通过链接的,不是吗?


I see many almost duplicates, e.g. here but no exact matches. Please correct me if I'm wrong in this regard.

我看到了许多几乎重复的东西,例如这里,但没有精确的匹配。如果我在这方面做错了,请纠正我。

6 个解决方案

#1


77  

Private structures for that file should go in the .c file, with a declaration in the .h file if they are used by any functions in the .h .

该文件的私有结构应该位于.c文件中,如果在.h中使用任何函数,则在.h文件中声明。

Public structures should go in the .h file.

公共结构应该放在.h文件中。

#2


54  

Both should result in the same usability, even if one is by linkage, shouldn't they?

两者都应该得到相同的可用性,即使一个是通过链接的,不是吗?

No, not when you consider other .c files including the same header. If the definition of the structure is not visible to the compiler, the details of that definition cannot be used. A declaration without a definition (e.g. just struct s;) causes the compiler to fail if anything tries to look inside struct s, while still allowing it to e.g. compile struct s *foo; (as long as foo is not later dereferenced).

不,当你考虑其他的。c文件,包括相同的标题。如果编译器不可见该结构的定义,则不能使用该定义的详细信息。没有定义的声明(例如,结构s;)如果试图查看内部结构,则编译器会失败,同时仍然允许编译结构s *foo;(只要foo没有被取消)。

Compare these versions of api.h and api.c:

比较这些版本的api。h和api.c:

Definition in header:                 Definition in implementation:
+---------------------------------+   +---------------------------------+
| struct s {                      |   | struct s;                       |
|     int internal;               |   |                                 |
|     int other_stuff;            |   | extern void                     |
| };                              |   | api_func(struct s *foo, int x); |
|                                 |   +---------------------------------+
| extern void                     |   +---------------------------------+
| api_func(struct s *foo, int x); |   | #include "api.h"                |
+---------------------------------+   |                                 |
+---------------------------------+   | struct s {                      |
| #include "api.h"                |   |     int internal;               |
|                                 |   |     int other_stuff;            |
| void                            |   | };                              |
| api_func(struct s *foo, int x)  |   |                                 |
| {                               |   | void                            |
|     foo->internal = x;          |   | api_func(struct s *foo, int x)  |
| }                               |   | {                               |
+---------------------------------+   |     foo->internal = x;          |
                                      | }                               |
                                      +---------------------------------+

This client of the API works with either version:

该API的客户端与任一版本兼容:

#include "api.h"

void good(struct s *foo)
{
    api_func(foo, 123);
}

This one pokes around in the implementation details:

这一项在实施细节中随处可见:

#include "api.h"

void bad(struct s *foo)
{
    foo->internal = 123;
}

which will work with the "definition in header" version, but not with the "definition in implementation" version, as in the latter case the compiler has no visibility of the layout of the structure:

这将与“标题的定义”版本一起工作,但与“实现的定义”版本不同,后者是编译器无法看到结构布局的可见性:

$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$

So, the "definition in implementation" version protects against accidental or deliberate misuse of private implementation details.

因此,“实现”版本的“定义”可以防止意外或故意地滥用私有实现细节。

#3


5  

If the struct is to be used by other compilation units (.c files) , place it in the header file so you can include that header file wherever it is needed.

如果结构被其他编译单元使用(。将它放在头文件中,这样您就可以在需要的地方包含这个头文件。

If the struct is only used in one compilation unit (.c file), you place it in that .c file.

如果结构仅用于一个编译单元(。c文件),你把它放在那个。c文件中。

#4


1  

The point is, placing it in a header file allows you to use the structure (or any other definition) from multiple source files, just by including that header file.

重点是,将它放在头文件中可以让您从多个源文件中使用结构(或任何其他定义),只需将该头文件包含进来即可。

But if you are sure it will only be used from one source file, then it really doesn't make any difference.

但是,如果您确信它只会从一个源文件中使用,那么它真的不会有任何影响。

#5


0  

I put them into the C file to make it more Object Oriented, see this article.

我把它们放到C文件中以使它更面向对象,看这篇文章。

#6


-2  

Generally, I don't think it makes a huge difference whether you put them in the header or source files. However, if you need to access the members of a structure from multiple source files, it is easier to put the structure in a header file and include it from any other files where the structure is needed.

一般来说,我不认为把它们放在头文件或源文件中会有很大的不同。但是,如果您需要访问来自多个源文件的结构的成员,则更容易将结构放入头文件中,并将其包含在需要结构的任何其他文件中。

#1


77  

Private structures for that file should go in the .c file, with a declaration in the .h file if they are used by any functions in the .h .

该文件的私有结构应该位于.c文件中,如果在.h中使用任何函数,则在.h文件中声明。

Public structures should go in the .h file.

公共结构应该放在.h文件中。

#2


54  

Both should result in the same usability, even if one is by linkage, shouldn't they?

两者都应该得到相同的可用性,即使一个是通过链接的,不是吗?

No, not when you consider other .c files including the same header. If the definition of the structure is not visible to the compiler, the details of that definition cannot be used. A declaration without a definition (e.g. just struct s;) causes the compiler to fail if anything tries to look inside struct s, while still allowing it to e.g. compile struct s *foo; (as long as foo is not later dereferenced).

不,当你考虑其他的。c文件,包括相同的标题。如果编译器不可见该结构的定义,则不能使用该定义的详细信息。没有定义的声明(例如,结构s;)如果试图查看内部结构,则编译器会失败,同时仍然允许编译结构s *foo;(只要foo没有被取消)。

Compare these versions of api.h and api.c:

比较这些版本的api。h和api.c:

Definition in header:                 Definition in implementation:
+---------------------------------+   +---------------------------------+
| struct s {                      |   | struct s;                       |
|     int internal;               |   |                                 |
|     int other_stuff;            |   | extern void                     |
| };                              |   | api_func(struct s *foo, int x); |
|                                 |   +---------------------------------+
| extern void                     |   +---------------------------------+
| api_func(struct s *foo, int x); |   | #include "api.h"                |
+---------------------------------+   |                                 |
+---------------------------------+   | struct s {                      |
| #include "api.h"                |   |     int internal;               |
|                                 |   |     int other_stuff;            |
| void                            |   | };                              |
| api_func(struct s *foo, int x)  |   |                                 |
| {                               |   | void                            |
|     foo->internal = x;          |   | api_func(struct s *foo, int x)  |
| }                               |   | {                               |
+---------------------------------+   |     foo->internal = x;          |
                                      | }                               |
                                      +---------------------------------+

This client of the API works with either version:

该API的客户端与任一版本兼容:

#include "api.h"

void good(struct s *foo)
{
    api_func(foo, 123);
}

This one pokes around in the implementation details:

这一项在实施细节中随处可见:

#include "api.h"

void bad(struct s *foo)
{
    foo->internal = 123;
}

which will work with the "definition in header" version, but not with the "definition in implementation" version, as in the latter case the compiler has no visibility of the layout of the structure:

这将与“标题的定义”版本一起工作,但与“实现的定义”版本不同,后者是编译器无法看到结构布局的可见性:

$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$

So, the "definition in implementation" version protects against accidental or deliberate misuse of private implementation details.

因此,“实现”版本的“定义”可以防止意外或故意地滥用私有实现细节。

#3


5  

If the struct is to be used by other compilation units (.c files) , place it in the header file so you can include that header file wherever it is needed.

如果结构被其他编译单元使用(。将它放在头文件中,这样您就可以在需要的地方包含这个头文件。

If the struct is only used in one compilation unit (.c file), you place it in that .c file.

如果结构仅用于一个编译单元(。c文件),你把它放在那个。c文件中。

#4


1  

The point is, placing it in a header file allows you to use the structure (or any other definition) from multiple source files, just by including that header file.

重点是,将它放在头文件中可以让您从多个源文件中使用结构(或任何其他定义),只需将该头文件包含进来即可。

But if you are sure it will only be used from one source file, then it really doesn't make any difference.

但是,如果您确信它只会从一个源文件中使用,那么它真的不会有任何影响。

#5


0  

I put them into the C file to make it more Object Oriented, see this article.

我把它们放到C文件中以使它更面向对象,看这篇文章。

#6


-2  

Generally, I don't think it makes a huge difference whether you put them in the header or source files. However, if you need to access the members of a structure from multiple source files, it is easier to put the structure in a header file and include it from any other files where the structure is needed.

一般来说,我不认为把它们放在头文件或源文件中会有很大的不同。但是,如果您需要访问来自多个源文件的结构的成员,则更容易将结构放入头文件中,并将其包含在需要结构的任何其他文件中。