2015-07-10 102 views
1

考虑下面的代码:如果发现初始化结构不修改所有成员

typedef struct _sMYSTRUCT_BASE 
{ 
    int b_a; 
    int b_b; 
    int b_c; 
} sMYSTRUCT_BASE; 

typedef struct _sMYSTRUCT 
{ 
    sMYSTRUCT_BASE base; 
    int   a; 
    int   b; 
} sMYSTRUCT; 

Private const sMYSTRUCT mystruct_init = 
{ 
    0, 
    1, 
    3, 
    4 
}; 

我正在寻找一种方式来产生一个错误(编译期或运行时),以表明结构初始化不是招”明确“触及”所有结构成员。 结构中有5个整数,但'mystruct_init'只有4个值。 我知道最后一个成员(mystruct_init.b)将为零,但我需要某种警告/错误来通知程序员这个错误。 这必须在一个非常旧的编译器上工作(可能甚至不符合ansi-c)。

+0

任何有这种方式的提示? – user2448122

回答

1

现代编译器能够在gcc中产生这样的警告......它使用-Wmissing-field-initializers(它会警告存在的初始化器,但不会初始化所有成员,但不会初始化没有初始化器的结构体表达式;这些至少有时可以通过打开来捕获-Wuninitialized,如果它看到你正在读取一个潜在的未初始化值,那么至少在你声明变量的同一函数中读取它时会警告你)。

如果你的老编译器碰巧提供了这样的警告,你当然可以打开它,但是这从你的描述中看起来不太可能。

我认为,如果您想对它们进行彻底搜索,您的最佳选择是查看是否可以使用某个版本的gcc编译代码 - 它不必编译得足够好实际运行在您的目标平台上以获取警告。我不能保证它能够编译你的ANSI之前的C代码,特别是当它广泛使用编译器特定的扩展时,但我至少可以说对现有的K & R语法的支持仍然存在于现代C标准,所以如果你的代码编译比你想象的更好,我不会感到惊讶。

如果可行,那么为了在IDE中始终如一地生成警告,您可以修改构建脚本,以便编译代码并将其链接到您所针对的真实编译器,并编译它(但不一定链接它)与gcc,只是为了产生额外的警告,可以拿起并显示的IDE。

另一种选择是查看是否可以找到可执行此类检查的兼容静态分析器;我使用名为EnSoft Atlas的工具来构建一个数据流图,通过检查未初始化的值是否会出现在结构字段中,它与简单的脚本一起可以用来比gcc警告更加彻底地执行初始化。

但是,我们对C的支持仍处于测试阶段。 Atlas要求Eclipse CDT(或JDT for Java)能够解析你的代码,而目前的C beta只完全支持现代的强类型结构初始化(即struct foo f = (struct foo) {...}已完全连接数据流,但支持较早的初始化列表语法struct foo f = {...}没有在我们的第一次通过实施),所以我不确定它现在能够满足您的需求。

+0

感谢您的详细回复。我正在使用[-Wmissing-field-initializers] gcc选项(因为它可以编译为使用gcc编码),但它给了我一些错误的肯定警告。请参阅[链接](http://stackoverflow.com/questions/22194935/wmissing-field-initializer-when-using-designated-initializers)。 - 初始化不是一个选项,因为这些初始化位于源的顶部(全局范围)。我将研究Atlas工具(我们使用Eclipse CDT进行开发),因为它可能很有趣... – user2448122

+0

我仔细查看了我们的工具对结构初始化程序的当前状态,它比我想象的要少一些时刻。我认为缺省字段的缺省值节点尚未实现。我将在添加完成后更新它。 –

+0

使用我们的工具已经可以识别丢失的初始值设定项,尽管......标记为“## tentative-definitions-only”的GlobalVariable节点已定义(不含'extern')但从未初始化,而本地(堆栈)未初始化的变量有一个未初始化的值流向它。 TypeOf边可以用于根据需要识别特定结构的结构或实例。 –