变量声明方法

4
我猜这是一个新手问题,但我好像错过了某些东西,而且我是个新手,所以如果答案很明显,不要太刻薄... 我看到变量有多种声明方式:
DataType varName = value;
DataType varName(value);
DataType varName{value};

我以为这是一种写作选择的情况,但最近我试图添加两个char变量并将其设置为另一个char变量,我使用了括号版本:

unsigned char sum{ char1 + char2 };

我收到了一个错误提示:

错误1:错误C2398:元素'1':从'int'到'unsigned char &'的转换需要进行缩小转换。

但是使用以下代码时,我没有遇到这个错误:

unsigned char sum(char1 + char2);

所以,能否有人解释一下这些声明之间的区别,或者提供一个链接给我看看?谢谢...

4
使用大括号可以避免缩窄转换,涉及非内置类型时会更加复杂。 - chris
这个问题的一个非常好的讨论可以在http://herbsutter.com/2013/05/09/gotw-1-solution/找到。 - sgvd
2个回答

1
TL;DR:将两个 char 相加会得到一个 int,大括号初始化有意禁止这样的赋值。在 C++ 中,遵循 C 的规则,对于加法进行整数提升;因此,表达式 char1 + char2(假设 char1 和 char2 都是 char 类型)的类型并不是像人们期望的 char,而是 int。相关标准的章节包括 §4.5(描述了整数提升)、§4.13(整数转换)和 §5.7(加法运算符诱导整数提升)。至于为什么会导致 unsigned char sum {char1 + char2}; 语句失败,大括号初始化是专门设计用来防止程序员进行缩小转换(§8.5.3),这可能会导致溢出。由于 int 至少是 char 的两倍大小(在八位可寻址机器上),因此这是一种缩小转换,所以会失败。

当然,最终你可能会停下来问自己,“添加两个字符到底意味着什么?”


*对于有兴趣的人,C++表示int足够大,可以至少容纳INT_MININT_MAX(§3.9.2)之间的值,并将这些宏的定义委托给C(§18.3.3.2),C将它们的最小值分别设为-32767和+32767(附录E,§1)。因此,int至少需要16位。char则至少需要8位。C还将char定义为一个字节宽度(§6.2.5.3,§5.2.1),其中一个字节(§3.6)是“可寻址的数据存储单元,足以容纳执行环境中基本字符集的任何成员。”严格来说,我认为根据这个定义,char可能比一个字节更大,但我相当确定它不会比任何其他类型更宽。

**那是-32767,而不是-32768。C并没有强制要求实现使用二进制补码表示有符号整数。


0

如果value不是DataType,并且该构造函数被写成explicit,则无法使用您的第一个示例。第二个示例将尝试调用带有参数value的构造函数,但如果它是explicit,则会起作用。第三个示例使用大括号可以防止缩小转换。


如果DataType的构造函数是explicit,第一个方法将无法工作。 - chris
@chris 没错,刚刚将答案做了修改。 - Paul Evans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接