如何在没有公共 header 文件的情况下共享数组类型定义?

how to share array type definition without common header file?

情况

我正在使用最小 GW 编译器:

>bin\cpp --version
cpp.exe (GCC) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我有两个 header 文件 main.hsubmodule.h。由于各种原因,我不能简单地将 header 中的一个包含到另一个中。


[更新]

I think you need to explain the various reasons why you cannot simply include one of this headers into the other because that's the obvious answer... – Andrew


我还有很多其他 *.h 文件包含 main.h 但不包含 submodule.h,它们不应该在子模块中隐藏一些东西。

submodule.h 定义了很多在 submodule.c 中实现的东西。 其中有一个数组类型定义和一个该类型的全局变量:

typedef const char INDEX_TABLE_t[42]; 
const INDEX_TABLE_t INDEX_TABLE;

submodule.c实现了这个数组:

const INDEX_TABLE_t INDEX_TABLE {/* 42 random char values */};

其他 *.h 个文件中使用了变量 INDEX_TABLE

char SOME_OTHER_INDEX[23] = {/* 23 random char values */};

#define SELECTOR_VALUE 5
#define a_fix_name INDEX_TABLE[SOME_OTHER_INDEX[SELECTOR_VALUE]]

这些 *.h 文件包括 main.h 但不包括 submodule.h

因此我过去常常将 INDEX_TABLE_tINDEX_TABLE_t 的(完全相同的)类型定义添加到 main.h 中,这样编译很好。

问题

我的客户使用代码分析工具 (QA-C) 抱怨类型的双重定义 INDEX_TABLE_t.

[C] More than one declaration of 'INDEX_TABLE_t' (with no linkage). 

客户让我修改代码,这样代码分析工具就不会再出现这个错误了。

我通常通过添加 extern 关键字来解决这个问题,除了一次。 但在这种情况下,编译器 抛出异常:

error: conflicting specifiers in declaration of 'INDEX_TABLE_t'

但是声明 是相等的(它们是基于模型呈现的)。

问题

我有机会让编译器和代码分析器都开心吗?

创建另一个 header 文件以包含在 main.h 或所有其他 *.h 文件中是我唯一的选择吗?

I have two header files main.h and submodule.h. For various reasons I cannot simply include one of this headers into the other.

那就帮自己一个忙,解决这个问题,即使您实际上 #include "submodule.h" 并不在 main.h 内。你说你不能这样做的说法闻起来很臭。

The submodule.c implements this array:

const INDEX_TABLE_t INDEX_TABLE {/* 42 random char values */};

您似乎在初始化程序之前省略了 =。此外,由于 INDEX_TABLE_t 是具有 const 元素的数组类型,我认为额外的 const 没有任何额外的效果。

My client uses a code alaysis tool (QA-C) that complains about the doubled definition of the type INDEX_TABLE_t.

[C] More than one declaration of 'INDEX_TABLE_t' (with no linkage). 

我想该工具关注的是声明在单独的文件中重复,而不是集中在一个 header 中。这是一个合理的担忧,与其说是为了程序 now,不如说是为了持续的维护和开发。您为未来的维护者(也许是未来的您)设置了一个陷阱,他们可能只更改其中一个类型定义,或者以不兼容的方式更改这两个,从而引入一个微妙但有影响的错误。

The client instructed me to change the code so that this error will no longer issued by the code analysis tool.

I usually solve this by adding the extern keyword to all but one occurrence. But in this case the compiler throws an exception:

error: conflicting specifiers in declaration of 'INDEX_TABLE_t'

But the declaratios are equal (they are rendered based on a model).

INDEX_TABLE_t 指定 类型 ,而不是 object 或函数。它不能有外部链接(根据 extern),因为它自动且必然有 no 链接。

Do I have any chance to make both happy, the compiler and the code analyser?

是的。

Is createing another header file to be included in in main.h or all the other *.h files my only option?

不完全是,但您确实需要将类型定义放在一个 header 中,并让您的所有来源直接或间接从那里获取它。您的想法的另一种选择是 #include 将 header 直接放入您的 .c 文件中,这可能需要仔细管理 #include 语句的顺序。

但总的来说,听起来您的 header collection 可以从一些重构中获益。作为一般规则,每个 header 应该(并且应该能够)包括为使用但未在其中声明的标识符提供声明所需的所有 header,而不是其他 header。这部分是通过在每个 header 中使用 include guards 来促进的。如果您从一开始就没有为它进行设计,那么可能还有其他方面的工作要做,但它肯定可以完成。


回复编辑后的问题

该软件的某些版本不包含 子模块 但(大概)确实使用了 main.h 这强烈表明 main.h 是错误的地方对于一个 typedef 对于一个 object 的类型,其中只有 子模块 提供了一个实例。它应该进入与 submodule 相关联的 header 或更广泛地与不同来源的 collection 相关联,这些来源都使用 submodule.

也许 header 本身就是 submodule.h。或许它应该是一个单独的 header,比如 submodule_general.h,对于现在 submodule.h 中的其他一些东西,它甚至可能是一个更好的地方。也许 submodule.h 中有一些不需要的东西,删除它——可能与将一些 object 和函数从外部转换为内部相结合——会使包含更容易接受submodule.h 在更多地方。

无论您在 header 之间拆分声明以避免重复并提供任何其他 objectives,您总是可以选择将 headers 包含到源中直接或通过其他 headers.

间接需要它们