-1

我天真地向 wchar_t 添加了一个 int 导致 Visual Studio 2013 警告。

L'A' + 1 // next letter

warning C4244: 'argument' : conversion from 'int' to 'wchar_t', possible loss of data

因此错误涉及到 4 字节 int 被隐式转换为 2 字节 wchar_t。很公平。

执行此操作的 C++ 11 标准安全方式是什么?我想知道跨平台的影响、代码点的正确性和可读性,比如:L'A' + (wchar_t)1L'A' + \U1其他。我的编码选项有哪些?

编辑 T+2:我向一个黑客小组提出了这个问题。不出所料,没有人正确。在招聘 C/C++ Unicode 程序员时,每个人都同意这是一个很好的面试问题,因为它非常简洁,值得深入讨论。

4

2 回答 2

1

当您将两个整数值相加时,两个值都可以放入一个int中,它们将作为ints 相加。

如果您需要 aunsigned int来适应其中一个,则将它们添加为unsigned ints。

如果这些不够大,可以使用更大的类型。它变得复杂,如果我没记错的话,它会随着标准修订而改变(那里有一些粗糙的地方)。

现在,int如果溢出,与 s 的加法是未指定的。与unsigned ints 相加可以保证将 mod 包装成 2 的幂。

当您将 anint或 an转换unsigned int为有符号类型时,如果它不适合,则未指定结果。如果它适合,它适合。

如果将intor转换unsigned int为无符号类型,则结果可以表示为等于源 mod 的 2 的某个幂(对于给定的无符号类型固定)。

许多流行的 C++ 编译器和硬件返回与2s 补码逻辑解释时相同的位模式,但这不是标准所要求的intunsigned int

因此L'A' + 1涉及将 L'A' 转换为int,添加1int.

如果我们添加缺少的位:

wchar_t bob = L'A' + 1;

我们可以看到警告发生的位置。编译器看到有人将 a 转换int为 awchar_t并警告他们。(当所讨论的值不是编译时常量时,这更有意义)

如果我们明确表示:

wchar_t bob = static_cast<wchar_t>(L'A' + 1);

警告(可能?希望?)消失了。只要右手边的结果在有效值的范围内wchar_t,你就是黄金。

相反,如果您正在做:

wchar_t bob = static_cast<wchar_t>(L'A' + x);

哪里xint, 如果wchar_t已签名,您可能会遇到麻烦(如果x足够大,则未指定结果!),如果它未签名,您仍然可能会有些惊讶。

这个static_cast方法的一个好处是,如果你不小心将指针输入(wchar_t)xwchar_t(x)强制转换中,它就不会起作用。

请注意,强制转换xor1是相对没有意义的,除非它使编译器安静下来,因为值总是在操作int之前+(或unsigned ints ifwchar_t是无符号且与 a 大小相同)向上转换(逻辑上)转换为 s int。如果是无符号的,则int比这大得多wchar_t是相对无害wchar_t的,因为保证反向转换与在wchar_tmod 中添加其 2 的幂相同,并且如果wchar_t有符号,则离开色域无论如何都会给出未指定的结果。

因此,使用static_cast. 如果这不起作用,请使用位掩码明确清除您不关心的位。

最后,VS2013 对int. 所以static_cast<wchar_t>(L'A' + x)并且总是产生相同的值,如果用or替换static_cast<wchar_t>( L'A' + static_cast<wchar_t>(x))就会这样做。wchar_tunsigned shortsigned short

这是一个糟糕的答案:它需要管理和剔除。但我累了,这可能很有启发性。

于 2014-05-22T02:40:27.037 回答
0

在我看到一个更优雅的答案之前,我希望有,我会采用这种模式:

(wchar_t)(L'A' + i)

我喜欢这种模式,因为i可以是消极的或积极的,它会按预期进行评估。如果是负数且未签名,我最初的使用概念L'A' + (wchar_t)i是有缺陷的。我在这里假设这取决于实现并且可以签名。iwchar_twchar_t

于 2014-05-21T22:28:56.147 回答