【发布时间】:2016-06-07 07:03:44
【问题描述】:
我编写了以下一段代码并通过 QA C 进行了分析,但它显示警告“x”具有外部链接,并且在没有任何先前声明的情况下定义。请帮助我理解这一点。
代码:
#include <stdio.h>
int x;
void main()
{
}
【问题讨论】:
-
QA C 是否设置为检查 MISRA 合规性,是否有机会?
标签: c
我编写了以下一段代码并通过 QA C 进行了分析,但它显示警告“x”具有外部链接,并且在没有任何先前声明的情况下定义。请帮助我理解这一点。
代码:
#include <stdio.h>
int x;
void main()
{
}
【问题讨论】:
标签: c
该工具正确地警告您不要使用不良的编程习惯。我怀疑这是因为您设置了静态分析器来检查 MISRA-C 合规性。
首先 MISRA-C 不允许“全局”变量,MISRA-C:2012 规则 8.7:
函数和对象不应使用外部链接定义,如果 它们仅在翻译单元中被引用。
表示此变量必须是static 或extern。
前者是有道理的,后者几乎总是非常糟糕的编程习惯(除了一些例外,比如一些const 变量)。
现在,如果您打算使用此变量 extern,那么还有另一条规则,这可能是错误的原因,MISRA-C:2012 规则 8.4:
当一个对象或函数时,一个兼容的声明应该是可见的 定义了外部链接。
这意味着为了符合 MISRA,您需要在同一个翻译单元中显示外部声明 extern int x。 MISRA 建议将其放在头文件中。
另请注意,此类错误代码已被标准标记为已过时,并且可能无法在 C 的未来版本中运行,请参阅 C11 6.11.2:
6.11.2 标识符的链接
在没有静态存储类的文件范围内声明具有内部链接的标识符 说明符是一个过时的功能。
即使它没有被 C 标记为过时的做法,您仍然应该始终避免使用全局变量和 extern,因为这是通向意大利面条式编程和意大利面条式紧耦合的道路。考虑完全不同的程序设计。
【讨论】:
这意味着x 可以在包含上述代码的翻译单元之外访问。所以它的值可以被其他翻译单元改变。
因此编译器会警告您可能会失去程序稳定性。
但是房间里的大象。修复那个不可移植的void main() 原型。使用int main()。很好,上面加糖。
【讨论】: