GCC默认使用4字节wchar_t
。我可以将选项-fshort-wchar
设置为wchar_t
中每L"string constants"
个2字节。但是当我将编译器选项设置为我的源文件时,我得到了着名的警告消息
foo.o使用2字节
wchar_t
但输出使用4字节wchar_t
;在对象中使用wchar_t
值可能会失败
因为我真的想要2字节wchar_t
我也希望输出使用这个变体。是否有任何链接器选项告诉它我想要什么?
修改
此警告不会禁止链接器生成有效输出。但是,数十个虚假警告涵盖了其他信息。
答案 0 :(得分:9)
在binutils中,您可以在bfd/elf32-arm.c
中找到此错误消息:
"警告:%B使用%u-byte wchar_t但输出是使用%u-byte wchar_t的;在对象中使用wchar_t值可能会失败"
但是,如果你仔细观察binutils,你就会意识到输出的wchar_t大小在任何地方都没有被初始化为4。那么什么决定了"输出wchar_t大小"?实际上,给ld
的第一个对象初始化输出属性。下一个对象将其属性合并到其中。如果您使用gcc / g ++进行链接,则会在内部执行ld
,因此请尝试gcc -v
并查看ld
的执行方式。这将使您深入了解内部对象文件(除了您自己的文件)隐式链接到您的可执行文件。
例如,使用gcc(例如gcc -v -shared -o libfoobar.so foo.o bar.o
)进行链接会导致调用:
ld ... crtbegin_so.o foo.o bar.o crtend_so.o ...
即。以下对象实际上是按顺序链接的:
这就是ld的作用:
out_attr[Tag_ABI_PCS_wchar_t] == 4
-fshort-wchar
构建的,那么in_attr[Tag_ABI_PCS_wchar_t] == 2
会导致冲突以及您看到的警告。如果您要在ld命令行上交换crtbegin_so.o和foo.o,则会收到以下警告:
ld:警告: 机器人-NDK-r9d /平台/机器人-16 /拱形臂/ usr / lib中/ crtbegin_so.o 使用4字节的wchar_t但输出是使用2字节的wchar_t;用于 跨对象的wchar_t值可能会失败
正如您所看到的,它不是输入与输出不兼容的问题,而是链接在一起的两个目标文件之间的(感知)不兼容。
我们能做些什么呢?
As of 2008,ld
支持--no-wchar-size-warning
标志以取消此警告。但正如你所说,不分青红皂白地压制警告有其缺点。
您可以使用-fshort-wchar重建工具链。
如果您真的相信他们是Tag_ABI_PCS_wchar_t
- 不可知的话,您可以从内部gcc对象二进制文件中删除sizeof(wchar_t)
标记。这可能比重建工具链更容易。为此,您可以使用我曾写过的this utility。 (您可能需要解压缩libgcc.a,更改其目标文件并重新打包。)
答案 1 :(得分:-1)
这是警告,而不是错误。您可以忽略它,但如果您链接到使用4字节wchar_t
编译的其他库,则会导致问题。如果你必须使用2字节wchar_t
,那么你必须找到这些库的替代品或重新编译它们
您也可以尝试-fwide-exec-charset=UTF-16
-fwide-exec-charset=charset
- 设置宽执行字符集,用于宽字符串和字符常量。默认值为UTF-32或UTF-16,取决于
wchar_t
的宽度。与-fexec-charset
一样,charset可以是系统的iconv库例程支持的任何编码;但是,如果编码不完全适合wchar_t
,则会遇到问题。
如果你有C11支持,你可以使用char16_t
(字符串文字的u
前缀)并在必要时转换为wchar_t