C 如何在没有公共头文件的情况下共享数组类型定义? 处境
我正在使用min GW编译器:C 如何在没有公共头文件的情况下共享数组类型定义? 处境,c,typedef,extern,qa-c,C,Typedef,Extern,Qa C,我正在使用min 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
>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.
我有两个头文件main.h
和submodule.h
。出于各种原因,我不能简单地将一个标题包含到另一个标题中
[更新]
我认为您需要解释为什么不能简单地将一个标题包含到另一个标题中的各种原因,因为这是显而易见的答案安德鲁
- 我无法将
导入main.h
,因为在这种情况下,submodule.h
中的更改将触发子模块的重新编译,尽管此处没有更改。编译时间是我的客户最关心的问题main.h
- 我不能将
包含到submodule.h
中,因为main.h
定义了很多东西,但只有少数定义是公开的。我的客户希望尽可能减少标识符的可见性submodule.h
- 我的客户端使用
的内容来验证目标软件不同版本的兼容性。上述数组的存在和大小是兼容性标准之一。因此,数组的定义必须保留在main.h
main.h
- 有些版本的目标软件根本没有子模块。因此,构建此子模块的文件可能存在,也可能不存在。对于我的客户来说,处理这种情况需要很多开销,而这些开销必须由其他人来完成,而不是我。因此,我的客户还想限制“闪烁”文件的数量
我还有很多其他
*.h
文件,包括main.h
,但不包括submodule.h
,它们不应该隐藏子模块中的某些内容
子模块.h
定义了许多在子模块.c
中实现的东西。
其中包括数组类型定义和该类型的全局变量:
typedef const char INDEX_TABLE_t[42];
const INDEX_TABLE_t INDEX_TABLE;
子模块.c
实现此数组:
const INDEX_TABLE_t INDEX_TABLE {/* 42 random char values */};
const INDEX_TABLE_t INDEX_TABLE {/* 42 random char values */};
变量INDEX_TABLE
在其他*.h
文件中使用:
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\u TABLE\u t
和INDEX\u TABLE\u t
的类型定义(完全相同)添加到main.h
,这样编译起来很好
问题
我的客户使用代码分析工具(QA-C),抱怨类型索引表\u t
的定义加倍
[C] More than one declaration of 'INDEX_TABLE_t' (with no linkage).
客户指示我更改代码,以便代码分析工具不再发出此错误
我通常通过将extern
关键字添加到除一次以外的所有事件中来解决此问题。
但在这种情况下,编译器会抛出一个异常:
error: conflicting specifiers in declaration of 'INDEX_TABLE_t'
error: conflicting specifiers in declaration of 'INDEX_TABLE_t'
但是声明是相等的(它们是基于模型呈现的)
问题
我有机会让编译器和代码分析器都高兴吗
创建另一个要包含在main.h
或所有其他*.h
文件中的头文件是我唯一的选择吗
我有两个头文件main.h
和submodule.h
。出于各种原因,我不能简单地将一个标题包含到另一个标题中
然后帮你自己一个忙,解决这个问题,即使你实际上没有在main.h
中包含“submodule.h”。你声称你不能这样做,这很难听
子模块.c
实现此数组:
const INDEX_TABLE_t INDEX_TABLE {/* 42 random char values */};
const INDEX_TABLE_t INDEX_TABLE {/* 42 random char values */};
您似乎在初始值设定项之前省略了一个=
。另外,由于INDEX\u TABLE\t
是一种包含const
元素的数组类型,我认为额外的const
没有任何额外的效果
我的客户使用代码分析工具(QA-C)抱怨
类型索引表的定义加倍
[C] More than one declaration of 'INDEX_TABLE_t' (with no linkage).
我认为该工具所关心的正是这样一个事实:声明在单独的文件中重复,而不是集中在单个头中。这是一个值得关注的问题,不是现在的项目,而是持续的维护和开发。您为未来的维护人员(可能是未来的您)设置了一个陷阱,他们可能只更改其中一个类型定义,或者以不兼容的方式更改这两个类型定义,从而引入了一个微妙但有影响的bug
客户指示我更改代码,这样就不会出现此错误
代码分析工具发布的更长时间
我通常通过将extern关键字添加到除一个之外的所有关键字来解决这个问题
发生。但在这种情况下,编译器会抛出一个异常:
error: conflicting specifiers in declaration of 'INDEX_TABLE_t'
error: conflicting specifiers in declaration of 'INDEX_TABLE_t'
但是声明是相等的(它们是基于模型呈现的)
INDEX\u TABLE\t
指定类型,而不是对象或函数。它不能有外部链接(根据extern
),因为它自动且必须有无链接
我有机会让编译器和代码都满意吗
分析仪
对
正在创建另一个要包含在main.h或all中的头文件
其他*.h文件是我唯一的选择吗
不完全是这样,但是您确实需要将类型定义放在一个标题中,并让所有源直接或间接地从那里获取它。一种替代方法是将该头直接包含到.c文件中,这可能需要仔细管理#include
语句的顺序
但总的来说,您的头集合似乎可以从重构中获益。作为一般规则,每个头应该(并且应该能够)包括所有需要的头,以提供所使用但未在其中声明的标识符的声明,而不包括其他头。这在一定程度上是通过在每个标题中使用include-guard来实现的。如果你从一开始就没有为它设计,那么可能还有其他方面可以让它发挥作用,但这是肯定的