【问题标题】:Understanding C linker error: multiple definition理解 C 链接器错误:多重定义
【发布时间】:2019-02-04 14:19:09
【问题描述】:

我有一个包含多个头文件和.cpp 文件的项目。 所有的头文件都有包含保护。

有一个名为Constants.h 的文件,我在其中定义了一些常量。其中一些带有定义,一些作为常量变量。

还有更多包含代码的 header-.cpp-file 对。其中一个确实包含一个类,其他的则不包含。

当我将我的文件包含到我的主文件(一个 arduino 草图)中时,我收到很多链接器错误,声称某些变量有多个定义。

我读到这主要发生在您包含 .c.cpp 文件时,我不这样做。所有.cpp 文件只包含其相应的头文件。

我确实设法找到了多个解决方案:

1) inline:

通过函数,inline 可以解决这个问题。但是,这对于变量是不可能的。

2) 匿名namespace:

这是我使用的解决方案之一。我在所有有问题的定义周围放置了匿名名称空间。它确实有效,但我不明白为什么会这样。谁能帮我理解一下?

3) 将定义移动到.cpp 文件中:

这是我有时使用的另一种方法,但并非总是可行,因为我需要在其他代码中定义一些不属于此头文件或其代码的定义(我承认这是糟糕的设计)。

谁能向我解释问题出在哪里以及为什么这些方法有效?

【问题讨论】:

  • @NathanOliver - 这个问题是关于 C 和 C++ 之间的细微差别。那个骗子是垃圾。
  • @StoryTeller 有一个名为 Constants.h 的文件,我在其中定义了一些常量。其中一些带有定义,一些作为常量变量。 看起来像是一个非常明确的 OP 在多个 TU 中包含变量定义。
  • @NathanOliver - 除了 C++ const whatever bar = foo; 在命名空间范围内默认具有内部链接。
  • 是否涉及C代码?否则你可能会删除 C 语言标签。

标签: c++ arduino include


【解决方案1】:

其中一些带有定义,一些作为常量变量。

在 C 中 const 与在 C++ 中的含义不同。如果你有这个:

const int foo = 3;

在标头中,任何包含标头的 C++ 翻译单元都将有一个名为foo静态 变量(命名空间范围内的const 意味着内部链接)。此外,foo 甚至可以被许多 C++ 构造视为常量表达式。

在 C 中情况并非如此。foo 是一个在文件范围内具有外部链接的对象。因此,您将有来自 C 翻译单元的多个定义。

快速解决方法是将定义更改为如下内容:

static const int foo = 3;

这在 C++ 中是多余的,但在 C 中是必需的。

【讨论】:

  • 这确实清楚了很多。将static 添加到有问题的定义中就可以了。我只是很惊讶我以前从未偶然发现过这个......
  • @Lithimlin - 通常 C 标头不会有这样的对象。并且 C++ 头文件将包含其他更可能不是有效 C 的内容。
【解决方案2】:

除了 Story Teller 的出色解释之外,要定义全局变量,请使用以下内容:

// module.h
#include "glo.h"

// glo.h
#ifndef EXTERN
# define EXTERN extern
#endif
EXTERN int myvar;

// main.c
#define EXTERN
#include "glo.h"

main.c 中,所有变量都将被声明(即为它们分配空间),在包含glo.h 的所有其他c 文件中,所有变量都将是已知的。

【讨论】:

    【解决方案3】:

    你不应该在头文件中声明任何对象,这应该被移动到 c\c++ 文件中。

    在标题中你可以:

    • 声明类型,例如:classes、structs、typedefs 等。
    • 提出(非类)函数的声明
    • 放入内联(或类中)函数(+ 正文)
    • 您可以添加extern 声明。
    • 你可以放你的宏。

    static 声明可能会声明多次,因此不推荐。

    【讨论】:

    • 声明很好。定义是造成麻烦的原因。
    • 我用constexpr double epsilon = 1e-6;反驳你的错误断言
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    相关资源
    最近更新 更多