为什么包含防护不能防止链接器错误?

发布于 2024-12-12 20:12:39 字数 506 浏览 2 评论 0原文

由于某种原因,即使我使用标头防护,我也会在标头文件中收到多个内容声明。我的示例代码如下:

main.c:

#include "thing.h"

int main(){
    printf("%d", increment());

    return 0;
}

thing.c:

#include "thing.h"

int increment(){
    return something++;
}

thing.h:

#ifndef THING_H_
#define THING_H_

#include <stdio.h>

int something = 0;

int increment();

#endif

当我尝试编译此代码时,GCC 说我有 some 变量的多个定义。 ifndef 应该确保这种情况不会发生,所以我很困惑为什么会这样。

For some reason, I'm getting multiple declarations of content within my header file even though I'm using header guards. My example code is below:

main.c:

#include "thing.h"

int main(){
    printf("%d", increment());

    return 0;
}

thing.c:

#include "thing.h"

int increment(){
    return something++;
}

thing.h:

#ifndef THING_H_
#define THING_H_

#include <stdio.h>

int something = 0;

int increment();

#endif

When I attempt to compile this, GCC says that I have multiple definitions of the something variable. ifndef should make sure that this doesn't happen, so I'm confused why it is.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

探春 2024-12-19 20:12:39

包含防护功能正常运行,并不是问题的根源。

发生的情况是,包含 thing.h 的每个编译单元都会获得自己的 int Something = 0,因此链接器会抱怨多个定义。

以下是解决此问题的方法:

thing.c:

#include "thing.h"

int something = 0;

int increment(){
    return something++;
}

thing.h:

#ifndef THING_H_
#define THING_H_

#include <stdio.h>

extern int something;

int increment();

#endif

这样,只有 thing.c 才会有 something 的实例,而 main.c 将引用它。

The include guards are functioning correctly and are not the source of the problem.

What happens is that every compilation unit that includes thing.h gets its own int something = 0, so the linker complains about multiple definitions.

Here is how you fix this:

thing.c:

#include "thing.h"

int something = 0;

int increment(){
    return something++;
}

thing.h:

#ifndef THING_H_
#define THING_H_

#include <stdio.h>

extern int something;

int increment();

#endif

This way, only thing.c will have an instance of something, and main.c will refer to it.

笔芯 2024-12-19 20:12:39

每个翻译单元中有一个定义(一个在 main.c 中,一个在 thing.c 中)。标头防护阻止标头在单个翻译单元中多次包含。

您需要在头文件中声明something,并且仅在thing.c定义它,就像功能:

thing.c:

#include "thing.h"

int something = 0;

int increment(void)
{
    return something++;
}

thing.h:

#ifndef THING_H_
#define THING_H_

#include <stdio.h>

extern int something;

int increment(void);

#endif

You have one definition in each translation unit (one in main.c, and one in thing.c). The header guards stop the header from being included more than once in a single translation unit.

You need to declare something in the header file, and only define it in thing.c, just like the function:

thing.c:

#include "thing.h"

int something = 0;

int increment(void)
{
    return something++;
}

thing.h:

#ifndef THING_H_
#define THING_H_

#include <stdio.h>

extern int something;

int increment(void);

#endif
柠栀 2024-12-19 20:12:39

标头防护将阻止文件在同一编译单元(文件)中被多次编译。您将其包含在 main.c 和 thing.c 中,因此它将在每个单元中编译一次,从而导致变量 something 在每个单元中声明一次,或者总共声明两次。

The header guards will stop the file from being compiled more than once in the same compilation unit (file). You are including it in main.c and thing.c, so it will be compiled once in each, leading to the variable something being declared once in each unit, or twice in total.

落花随流水 2024-12-19 20:12:39

尽量避免全局定义变量。
使用像increment()这样的函数来修改和读取它的值。
这样您就可以在 thing.c 文件中保持变量静态,并且您可以确定只有该文件中的函数才会修改该值。

try to avoid defining variables globally.
use functions like increment() to modify and read its value instead.
that way you can keep the variable static in the thing.c file, and you know for sure that only functions from that file will modify the value.

○愚か者の日 2024-12-19 20:12:39

变量 something 应该在 .c 文件中定义,而不是
在头文件中。

仅变量和函数原型的结构、宏和类型声明
应该在头文件中。在您的示例中,您可以在头文件中将 something 的类型声明为 extern int some 。但变量本身的定义应该在 .c 文件中。

根据您所做的操作,变量 something 将被定义
在包含 thing.h每个 .c 文件中,您会得到一个
GCC 尝试链接时出现“多次定义的内容”错误消息
一切都在一起。

The variable something should be defined in a .c file, not
in a header file.

Only structures, macros and type declarations for variables and function prototypes
should be in header files. In your example, you can declare the type of something as extern int something in the header file. But the definition of the variable itself should be in a .c file.

With what you have done, the variable something will be defined
in each .c file that includes thing.h and you get a
"something defined multiple times" error message when GCC tries to link
everything together.

焚却相思 2024-12-19 20:12:39

ifndef 所保护的是一个 .h 多次包含在 .c 中。比如

事情。 h

#ifndef
#define

int something = 0;
#endif

thing2.h

#include "thing.h"

main.c

#include "thing.h"
#include "thing2.h"
int main()
{
  printf("%d", something);
  return 0;
}

如果我离开 ifndef 那么 GCC 会抱怨

 In file included from thing2.h:1:0,
             from main.c:2:
thing.h:3:5: error: redefinition of ‘something’
thing.h:3:5: note: previous definition of ‘something’ was here

what ifndef is guarding is one .h included in a .c more than once. For instance

thing. h

#ifndef
#define

int something = 0;
#endif

thing2.h

#include "thing.h"

main.c

#include "thing.h"
#include "thing2.h"
int main()
{
  printf("%d", something);
  return 0;
}

if I leave ifndef out then GCC will complain

 In file included from thing2.h:1:0,
             from main.c:2:
thing.h:3:5: error: redefinition of ‘something’
thing.h:3:5: note: previous definition of ‘something’ was here
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文