【问题标题】:C Guard not work as intended with rlutil.hC Guard 不能按预期与 rlutil.h 一起工作
【发布时间】:2017-10-06 03:18:03
【问题描述】:

我正在尝试使用rlutil.h,但每次在多个头文件中使用这些函数时,我都会遇到关于 20-30 个变量的多重定义的编译器错误。 rlutil 是一个简单的头文件,用于在 linux 中为终端着色,在 C 和 C++ 中为 windows 着色。

变量是这样的

const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_POST = "\007";

和 typedef 类似的东西

typedef const char* RLUTIL_STRING_T;

我尝试添加自己的 C 防护,但没有奏效。 我尝试将 .h 与我自己的 .h/.c 分层以使用 rlutil.h 函数创建新函数,但问题仍然存在。 我试图将变量设为外部,但这是最糟糕的

我在 ubuntu 上使用 gcc 构建它。 我会在家里用 MVSC2017 试试这个,但我认为行为会是一样的。

有什么想法吗?

我可以提供更多信息。 对不起我的英语我不是母语人士

非常感谢

【问题讨论】:

  • 它有#pragma once,应该防止它被多次包含。
  • 是否有可能重复出现在另一个文件中,并且编译器意外发生在该文件上?
  • 我看到了,但没有
  • 从 rlutil.h 读取 cmets - 每当我看到“Here be magic”和“Here be dragons”时,我都非常担心代码不可移植,并且可能几乎无法在预期目标上运行。
  • 错误发生 20-30 次,我不在其他文件中使用这种变量。只需包含我的标题层或标题 2 或更多时间就可以实现。

标签: c gcc header guard


【解决方案1】:

问题在于,标头仅设置为可以与 C++ 一起使用,其中标头 rlutil.h 中定义的 const 值对每个翻译单元 (TU) 都是私有的 - 认为源文件加上标头 - 即包括标题。相比之下,在 C 中,它们是在包含rlutil.h 的每个 TU 中定义的普通全局变量,从而导致多定义问题。

没有简单的解决方法——除非从 C 切换到 C++ 被认为是微不足道的。标头尝试在 C 和 C++ 之间保持语言中立,但在此计数上失败了。再次证明 C 和 C++ 是不同的语言。

在 C 语言中,您需要如下代码:

extern const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_POST;

在标题中,然后一个源文件将定义值:

const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_POST = "\007";  // James Bond!

或者,您可以考虑在标题中使用static

static const RLUTIL_STRING_T ANSI_CONSOLE_TITLE_POST = "\007";

每个包含此标头的 C 文件都有自己的已定义变量集合。在 C 中,您会受到关于未使用变量的编译器警告,这是不可取的。在 C++ 中,您可能会收到有关使用 static 而不是匿名命名空间的警告。因此,尚不清楚这是一个好的解决方案。

如果你够勇敢,你可以阅读我对How do I use extern to share variables between files 的回复,但标题可能不在你的控制范围内,你真的需要向代码的维护者报告问题。 (如果您是维护者,请考虑其他问题的答案中概述的方案是否会有所帮助。)

【讨论】:

  • 谢谢,我刚刚添加了一个带有声明的 .c 并在 .h 上添加了“extern” 解释很完美,我学到了很多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多