0

我遇到了一个非常奇怪的问题...如果将以下琐碎的测试代码注入到单个Cocoa应用程序中,它应该可以正常工作,但是当我在其中一个框架中使用它时,我会得到绝对出乎意料的结果...

wchar_t Buf[2048];
wcscpy(Buf, L"/zbxbxklbvasyfiogkhgfdbxbx/bxkfiorjhsdfohdf/xbxasdoipppwejngfd/gjfdhjgfdfdjkg.sdfsdsrtlrt.ljlg/fghlfg");
int len1 = wcslen(L"/zbxbxklbvasyfiogkhgfdbxbx/bxkfiorjhsdfohdf/xbxasdoipppwejngfd/gjfdhjgfdfdjkg.sdfsdsrtlrt.ljlg/fghlfg");
int len2 = wcslen(Buf);

char Buf2[2048];
Buf2[0]=0;
wcstombs(Buf2, Buf, 2048);

// ??? Buf2 == ""
// ??? len1 == len2 == 57, but should be 101


怎么会这样,我疯了吗?即使存在内存损坏,它也不可能损坏分配在堆栈上的所有这些值......为什么连wcslen(L"MyWideString")都不起作用?更改测试字符串会更改其长度,但总是错误的,wcstombs返回 -1 ...

setlocale()不在任何地方使用,测试字符串仅包含ASCII字符,为了便于移植,我使用-fshort-wchar编译器选项,但在测试 Cocoa 应用程序的情况下它可以正常工作...

请帮忙!

4

3 回答 3

0

我刚刚用 GCC 4.6 再次测试了这个。在标准设置中,这可以按预期工作,所有长度都为 101。但是,通过您的选择,-fshort-wchar我也会得到意想不到的结果(在我的情况下为 51,使用 setlocale() 后的最终转换为 251)。

因此,我查找了该选项的 man 条目:

警告:-fshort-wchar 开关导致 GCC 生成的代码与没有该开关生成的代码二进制不兼容。使用它来符合非默认应用程序二进制接口。

我认为这可以解释:当您链接到标准库时,您应该使用正确的 ABI 和类型约定,您将使用该选项覆盖这些约定。

于 2011-06-20T21:54:09.873 回答
0

-fshort-wchar更改编译器的 ABI,因此需要重新编译 glibc、libgcc 和所有使用 wchar_t 的库。否则,glibc 中的 wcslen 和其他函数仍假定 wchar_t 为 4 个字节。

见:http ://gcc.gnu.org/bugzilla/show_bug.cgi?id=42092

于 2012-03-27T08:29:33.603 回答
0

C/C++ 中的宽字符实现可以是任何字符,包括 1 字节、2 字节或 4 字节。这取决于编译器和您要编译到的平台。

维基百科可能不是引用的最佳地点,但在这种情况下: http ://en.wikipedia.org/wiki/Wide_character指出

... wchar_t 的宽度是特定于编译器的,可以小至 8 位。

... 由于历史兼容性原因,宽字符在 C90 下应为 16 位值。符合 10646-1:2000 Unicode 标准的 C 和 C++ 编译器通常采用 32 位值......

所以,不要假设和使用sizeof(wchar_t).

于 2011-06-14T10:47:58.163 回答