我天真地在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)1
或L'A' + \U1
或其他什么。我的编码选项是什么?
编辑T + 2:我向黑客小组提出了这个问题。不出所料,没人理解。每个人都认为这是一个很好的面试问题,因为它非常简洁,值得进行丰富的对话。
答案 0 :(得分:0)
直到我看到一个更优雅的答案,我希望有,我会采用这种模式:
(wchar_t)(L'A' + i)
我喜欢这种模式,因为i
可以是负数或正数,它会按预期进行评估。如果L'A' + (wchar_t)i
为否定且i
未签名,则我使用wchar_t
的原始概念存在缺陷。我在此假设wchar_t
依赖于实现并且可以签名。
答案 1 :(得分:0)
当您将两个整数值相加时,两个值都可以放在int
中,它们会被添加为int
。
如果您需要unsigned int
以适合其中一个,则会将其添加为unsigned int
s。
如果那些不够大,可以使用更大的类型。如果我记得正确(那里有一些粗糙的地方),它会变得复杂,并且会根据标准修订进行更改。
现在,如果溢出,则添加int
s是未指定的。使用unsigned int
s的加法保证将mod包含为2的幂。
将int
或unsigned int
转换为签名类型时,如果不符合,则结果未指定。如果它确实适合,它就适合。
如果将int
或unsigned int
转换为无符号类型,则可以表示的值等于源mod的某个幂为2(对于给定的无符号类型是固定的)是结果。
许多流行的C ++编译器和硬件返回int
的相同位模式,就像2s补码逻辑所解释的unsigned int
一样,但标准并不要求这样做。
所以L'A' + 1
涉及将L'A'转换为int
,将1
添加为int
。
如果我们添加遗漏位:
wchar_t bob = L'A' + 1;
我们可以看到警告发生的位置。编译器看到某人将int
转换为wchar_t
并向其发出警告。 (当有问题的值不是编译时常量时,这更有意义)
如果我们明确说明:
wchar_t bob = static_cast<wchar_t>(L'A' + 1);
警告(可能?希望?)消失了。只要右侧导致处于有效wchar_t
值的范围内,您就是金色的。
如果您正在这样做:
wchar_t bob = static_cast<wchar_t>(L'A' + x);
其中x
是int
,如果wchar_t
已签名您可能遇到麻烦(如果x
足够大,则表示未指定的结果!),如果未签名,则仍然有些惊讶。
这个static_cast
方法的一个好处是,与(wchar_t)x
或wchar_t(x)
强制转换不同,如果您不小心将指针提供给强制转换,它将无效。
请注意,转换x
或1
相对没有意义,除非它使编译器静默,因为值始终在{{1}之前被转换(逻辑上)到int
s之前操作(或+
如果unsigned int
是无符号且与wchar_t
相同的大小)。如果int
未签名,int
明显大于wchar_t
,则相对无害,因为后转换保证与添加wchar_t
mod的功能相同两个,如果签署了wchar_t
,那么无论如何都会给出一个未指定的结果。
因此,使用wchar_t
投射结果。如果这不起作用,请使用位掩码明确清除您不关心的位。
最后,VS2013对static_cast
使用2s补码数学。因此,int
和static_cast<wchar_t>(L'A' + x)
始终生成相同的值,如果static_cast<wchar_t>( L'A' + static_cast<wchar_t>(x))
替换为wchar_t
或unsigned short
,则会生成相同的值。
这是一个糟糕的答案:它需要策展和剔除。但我很累,这可能很有启发性。