如何禁止在编译时使用全局变量

Ita*_*rom 21 c compiler-construction gcc

有没有办法禁止使用全局变量?

我希望GCC在定义全局变量时在编译时生成错误.

我们有一个应该按线程运行的代码,并且只允许使用堆栈(这是线程安全的)

有办法强制执行吗?

一些GCC标志或其他方式来验证它?

小智 17

一种方法是生成链接器映射文件(例如,将选项-Wl,-Map,program.map传递给gcc),并检查.data.bss输出节,以查找要运行的目标文件的任何贡献.全局.

例如,如果我的源文件hello.c具有:

static int gTable[100];
Run Code Online (Sandbox Code Playgroud)

链接器映射文件将包含这样的内容:

.bss            0x0000000000600940      0x1b0
 *(.dynbss)
 .dynbss        0x0000000000000000        0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
 *(.bss .bss.* .gnu.linkonce.b.*)
 .bss           0x0000000000600940        0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
 .bss           0x0000000000600940        0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o
 .bss           0x0000000000600940        0x1 /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
 *fill*         0x0000000000600941       0x1f 00
 .bss           0x0000000000600960      0x190 hello.o
Run Code Online (Sandbox Code Playgroud)

您可以看到hello.o.bss部分贡献了0x190(400)个字节.我使用了使用Python脚本解析链接映射文件的方法,为嵌入式项目生成代码大小和RAM使用指标,并且过去取得了相当的成功; 链接器的文本输出格式非常稳定.

  • 使用链接描述文件,您还可以将`.data`部分的存在转换为错误 - 您将它们映射到零长度输出区域. (4认同)
  • +1这个答案和Simon的评论是在构建系统中强制执行非全局规则的正确要素. (2认同)
  • 变体1:`ASSERT(SIZEOF(.data))== 0,"不允许全局数据") (2认同)

Woj*_*wka 8

在gcc中没有这样的功能.一些解决方法是在构建过程中加入一个可以检测全局变量的静态分析工具.编译不会失败,但至少你会以某种方式受到警告.我可以看到PC-Lint(www.gimpel.com)有一张支票

非const非易失性全局变量,定位这些变量可以帮助多线程应用程序检测非重入情况

可能其他工具可能包括类似的功能.

  • 我正在考虑使用nm或objdump来扫描全局变量并打印警告 (2认同)
  • @ItayMarom`readelf -s a.out | grep GLOBAL | grep OBJECT` (2认同)