c - 使用 GCC 链接器强制执行 32 位枚举

标签 c gcc enums arm ld

我正在为 ARM 设备(无操作系统)编写裸机应用程序。我需要 32 位枚举,因此我使用 -fno-short-enums 编译器标志编译了应用程序。如果没有此标志,我将获得变量枚举(并通过向每个枚举添加额外的 0xFFFFFFFF 值来强制大小不是一种选择)。

现在我对每个对象都收到以下链接器警告:

c:/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: ./src/test.o uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail

这只是一个警告,没有错误。但这到底是什么意思呢?如何指定“输出”?

我尝试使用上述标志重新编译 newlib 以确保所有对象使用相同的枚举大小,但我仍然收到警告。我错过了什么吗?

最佳答案

一段时间后,我开始工作了。 我用这个标志重建了整个工具链,包括编译器。这是我的做法:

  1. https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads 获取工具链来源

  2. 在构建脚本 build-toolchain.sh 的某些部分添加 3 行:

    saveenv
    saveenvvar CFLAGS_FOR_TARGET '-fno-short-enums'
      [...build commands...]
    restoreenv
    

    修改部分:

    • 任务 [III-1]/$HOST_NATIVE/gcc-first/
    • 任务 [III-2]/$HOST_NATIVE/newlib/
    • 任务 [III-4]/$HOST_NATIVE/gcc-final/
    • 任务 [IV-3]/$HOST_MINGW/gcc-final/

    我跳过了构建 newlib-nanogcc-size-libstdcxx

  3. 运行修改后的脚本 build-prerequisites.shbuild-toolchain.sh 来构建所有内容。


在那之后,编译器使用大枚举模式,链接器可以正常处理我的对象。但是现在,我收到了 newlib 的某些对象的相反警告(lib_a-mbtowc_r.olib_a-svfiprintf.olib_a-svfprintf.o, lib_a-vfprintf.olib_a-vfiprintf.o):

c:/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: c:/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/6.2.1/../../../../arm-none-eabi/lib\libc.a(lib_a-mbtowc_r.o) uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail

我查看了这些对象的 makefile,遗憾的是它们被显式设置为 variable-size-enums。唯一的“解决方案”是添加一个链接器标志以消除此警告:

-Xlinker -no-enum-size-warning

就是这样。

关于c - 使用 GCC 链接器强制执行 32 位枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43890117/

相关文章:

c - 由于类型转换,二进制值到浮点值的转换不起作用

c - 使用另一个编译器更快的代码

c++ - 如何更新到 C++11?

dictionary - Elixir获得的值在 map 中不为空

.net - 显式定义枚举值时 WCF 客户端失败

C 程序给出意外的输出

c++ - 3d数组c/c++初始化/转换

c - 此函数声明在 ‘;’ token 之前抛出错误 : expected ‘,’ , ‘)’ 或 ‘=’

GCC交叉编译器目标库安装目录

构造函数中带有枚举的java枚举