gpt4 book ai didi

c - #include <...> 项的顺序在 C 中很重要吗?

转载 作者:行者123 更新时间:2023-12-05 01:22:20 25 4
gpt4 key购买 nike

下面两组 #include 行之间有区别吗?

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

编码风格重要吗?

顺序对任何优化有影响吗?

这是编码约定的问题吗?

最佳答案

#include 将包含文件的内容转储到当前文件中。

如果包含的文件是一个编写正确、行为良好的 header ,那么就没有区别,这无关紧要,对代码风格也不重要。

有一些异常(exception)。


GNU basename(3)说:

There are two different versions of basename() - the POSIX versiondescribed above, and the GNU version, which one gets after

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <string.h>

The GNU version never modifies its argument, and returns the emptystring when path has a trailing slash, and in particular also when itis "/". There is no GNU version of dirname().

With glibc, one gets the POSIX version of basename() when <libgen.h>is included, and the GNU version otherwise.

假设您包含 libgen.h - 您将获得 POSIX 版本。但随后您包含 string.h - 它会覆盖 libgen.h 吗?这在很大程度上取决于两者的实现,并且可能在某些版本中确实如此,或者,如果您在某些版本中首先包含 string.h 然后是 libgen.h libgen.h 不会覆盖 string.h 的 GNU 版本。


_GNU_SOURCE 本身也是一个示例。

例如,您得到 mempcpy(3)仅当您这样做时:

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <string.h>

同样你会得到 accept4(2)仅当您这样做时:

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <sys/socket.h>

现在让我们说无论出于何种原因您想要 mempcpy(3) 而不是 accept4(2)

你必须做的:

#include <sys/socket.h>
#define _GNU_SOURCE
#include <string.h>

你不能在 socket.h 之前包含 string.h 因为那样你就必须将 _GNU_SOURCE 向上移动,然后得到accept4(2),否则不上移,不获取mempcpy(3)


另一个例子是内联代码生成器:

generator.h:

GENERATE(api_func_a)
GENERATE(api_func_b)
GENERATE(api_func_c)
GENERATE(api_func_d)
GENERATE(api_func_e)
GENERATE(api_func_f)

server.h:

#define GENERATE(api_func) int server_##api_func(const char* msg);
#include "generator.h"
#undef GENERATE

client.h:

#define GENERATE(api_func) int client_##api_func(const char *msg);
#include "generator.h"
#undef GENERATE

如您所见,generator.h 被包含在特定情况下,这些情况在很大程度上取决于事先定义的内容。

你应该能够做到:

#include "server.h"
#include "client.h"

按照这个顺序或相反的顺序...除非有人忘记了 #undef 部分。


由于复制粘贴错误,又出现了另一个排序问题:

api_a.h:

#ifndef API_A_H
#define API_A_H

int api_a(int arg);

#undef API_A_H

复制并粘贴到api_b.h:

#ifndef API_A_H
#define API_A_H

int api_b(const char* arg1, int arg2);

#undef API_A_H

consumer.h:

#include "api_a.h"
#include "api_b.h"

... api_a(1) ...
...
... api_b("b", 2) ...

结果:api_b 未定义。如果我颠倒顺序:

#include "api_b.h"
#include "api_a.h"

我得到 api_a 未定义。

这是为什么呢?因为复制粘贴api_a.hapi_b.h时,我忘记修改包含保护API_A_HAPI_B_H,所以当包含第二个文件时,它会看到 API_A_H,并跳过 API 的定义。

关于c - #include <...> 项的顺序在 C 中很重要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74333418/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com