如何设置2个字节的wchar_t输出? [英] How to set 2 byte wchar_t output?
问题描述
默认情况下,GCC使用4字节的wchar_t
.我可以将选项-fshort-wchar
设置为在L"string constants"
中每个wchar_t
获得2个字节.但是,当我将编译器选项设置为源文件时,会收到著名的警告消息
The GCC uses a 4-byte wchar_t
by default. I can set the option -fshort-wchar
to get 2 bytes per wchar_t
in the L"string constants"
. But when I set the compiler option to my source file I get the famous warning message
foo.o使用2字节
wchar_t
,但输出将使用4字节wchar_t
.在对象之间使用wchar_t
值可能会失败
foo.o uses 2-byte
wchar_t
yet the output is to use 4-bytewchar_t
; use ofwchar_t
values across objects may fail
因为我真的想要2字节wchar_t
,所以我也希望输出使用此变体.有链接器选项可以告诉我我想要什么吗?
Since I really want 2-byte wchar_t
I also want the output to use this variant. Is there any linker option to tell it what I want?
修改
此警告不会阻止链接器产生有效的输出.但是数十种虚假警告涵盖了其他消息.
This warning doesn't inhibit the linker to produce a valid output. But the dozens of false warnings cover other messages.
推荐答案
在binutils中,您可以在bfd/elf32-arm.c
中以以下方式找到此错误消息:
In binutils you can find this error message in bfd/elf32-arm.c
as:
警告:%B使用%u字节wchar_t,但输出将使用%u字节 wchar_t;在对象之间使用wchar_t值可能会失败"
"warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
但是,如果您进一步看一下binutils,您会发现输出的wchar_t大小不会在任何地方初始化为4.那么,什么决定了输出wchar_t大小"呢?实际上,赋予ld
的第一个对象初始化输出属性.接下来的对象将其属性合并到其中.如果与gcc/g ++链接,它将在内部执行ld
,因此请尝试gcc -v
并查看如何执行ld
.这将使您深入了解它隐式链接到可执行文件中的内部对象文件(除了您自己的文件之外).
However, if you look further at binutils, you'd realize that the output's wchar_t size is not initialized to 4 anywhere. So what determines the "output wchar_t size"? Actually, the first object given to ld
initializes the output attributes. The next objects merge their attributes into it. If you link with gcc/g++, it executes ld
internally, so try gcc -v
and see how ld
is executed. This will give you insight into what internal object files (in addition to your own) it implicitly links into your executable.
例如,与gcc链接(例如gcc -v -shared -o libfoobar.so foo.o bar.o
)会导致调用:
For example, linking with gcc (e.g. gcc -v -shared -o libfoobar.so foo.o bar.o
) results in invocation of:
ld ... crtbegin_so.o foo.o bar.o crtend_so.o ...
即实际链接了以下对象(按顺序):
i.e. the following objects are actually linked (in order):
- crtbegin_so.o(暗含)
- foo.o
- bar.o
- crtend_so.o(暗含)
这是ld的作用:
- 输出属性集开始为空.
- 合并 crtbegin_so.o 属性.现在输出属性包含
out_attr[Tag_ABI_PCS_wchar_t] == 4
- 合并 foo.o 属性.如果foo.o是用
-fshort-wchar
构建的,则in_attr[Tag_ABI_PCS_wchar_t] == 2
会导致冲突和您看到的警告.
- The output attributes set starts off empty.
- Merging crtbegin_so.o attributes. Now output attributes contain
out_attr[Tag_ABI_PCS_wchar_t] == 4
- Merging foo.o attributes. If foo.o was built with
-fshort-wchar
, thenin_attr[Tag_ABI_PCS_wchar_t] == 2
and this will result in a conflict and the warning you're seeing.
如果要在ld命令行上交换crtbegin_so.o和foo.o,则会收到以下警告:
If you were to swap crtbegin_so.o and foo.o on the ld command line, you'd get the following warning instead:
ld:警告: android-ndk-r9d/platforms/android-16/arch-arm/usr/lib/crtbegin_so.o 使用4字节wchar_t,但输出将使用2字节wchar_t;用于 跨对象的wchar_t值可能会失败
ld: warning: android-ndk-r9d/platforms/android-16/arch-arm/usr/lib/crtbegin_so.o uses 4-byte wchar_t yet the output is to use 2-byte wchar_t; use of wchar_t values across objects may fail
如您所见,这不是输入与输出不兼容的问题,而是链接在一起的两个目标文件之间(可感知的)不兼容的问题.
As you can see, it's not a matter of incompatibility of the input with the output, but rather (perceived) incompatibility between two object files linked together.
我们该怎么办?
-
从2008年起,
ld
支持--no-wchar-size-warning
标志可禁止显示此警告.但是正如您所说,不加选择地禁止警告有其弊端.
As of 2008,
ld
supports the--no-wchar-size-warning
flag to suppress this warning. But as you said, indiscriminately suppressing warnings has its drawbacks.
您可以使用-fshort-wchar重建工具链.
You can rebuild your toolchain with -fshort-wchar.
如果您确实相信Tag_ABI_PCS_wchar_t
不可知,则可以从内部gcc对象二进制文件中剥离Tag_ABI_PCS_wchar_t
标记.这可能比重建工具链更容易.为此,您可以使用我曾经写过的此实用程序. (您可能需要解包libgcc.a,更改其目标文件并重新打包.)
You can strip the Tag_ABI_PCS_wchar_t
tags from your internal gcc object binaries if you truly believe they're sizeof(wchar_t)
-agnostic. This might be easier than rebuilding your toolchain. For that, you can use this utility I once wrote. (You might need to unpack libgcc.a, change its object files and repack it.)
这篇关于如何设置2个字节的wchar_t输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!