我在我的项目中违反了米斯拉5.2的规则。我得到违犯的代码是一个在一个头文件中声明为extern的结构。代码示例如下所示
1.h
extern struct con tmp_ev;2.c
struct con tmp_ev;
cioF_get(&tmp_ev);3.c
struct con tmp_ev;
(void)eeF_read(CON, &tmp_ev);我只在struct con tmp_ev;行的2.c中收到警告,它说
符号tmp_ev的声明隐藏符号tmp_ev
而不是在3.c。2.c和3.c都包含1.h头文件。
我搞不懂为什么会出现这个问题。有人能帮我解决这个问题吗?
发布于 2018-03-01 16:38:19
规则5.2规定,本地作用域中的变量不应隐藏同名的全局变量。
您有名为tmp_ev的局部变量和同名的全局变量。本地的那个在跟踪全球的那个。重命名本地的或全局的。
发布于 2018-03-02 23:17:34
您应该了解C-对象的“声明”和“定义”之间的区别。对象可能只有一个“定义”,而任意地有许多“声明符”。“声明”仅仅是一个物体存在的状态。“定义”确立了这种存在。extern总是一个对象的声明(或“这里”),而不是一个“定义”。
C文件中没有extern的声明extern总是在C文件中生成variable的定义(称为“暂定定义”)。
我不太熟悉misra (目前正在学习它),但是您的体系结构很混乱:
文件1.h声明了一个具有全局范围的外部tmp_ev。
2.c文件定义了一个具有全局范围的变量tmp_ev。(“暂定定义”)。
文件3.c还定义了另一个具有全局范围的变量tmp_ev (同样是一个“暂定定义”)。
所以C文件中tmp_ev的两个定义是相互竞争的。现在您应该决定哪个C文件(别名“编译单元”)有权定义tmp_env。所有其他C-文件都应该使用extern声明,最好是由#include "1.h"声明.
请注意,C文件可以“声明”它“定义的”变量。在C程序员中,一个常见的习语是在某些头foo_var中声明变量foo.h并在一个名为foo.c的相关C文件中定义变量,该文件本身包括foo.h。
发布于 2018-04-05 11:47:55
所提供的代码片段不应生成MISRA-C:2004规则5.2违规,因为不存在内部作用域和外部作用域的嵌套。
但是,这违反了MISRA:2004规则8.9,因为在全局范围内有两个(暂定的) tmp_ev定义。
注:也正在“正式”米斯拉论坛上讨论,并产生了以下答复:
规则5.2仅适用于内部作用域中的标识符。从示例中可以看出,2.c和3.c中的代码是存在于文件范围还是在函数中。 如果函数定义中出现2.c和3.c中的"struct tmp_ev“,将违反规则5.2。 如果"struct tmp_ev“出现在文件范围内,就违反了规则8.9,因为项目中有两个(暂定的) "struct tmp_ev”定义。
https://stackoverflow.com/questions/49054369
复制相似问题