从我从得到的回答这个问题,看来C++继承了这一要求,对于转换short成int从C.执行算术运算时,我可以挑你的大脑,以为什么这是用C首先介绍?为什么不做这些操作short呢?
例如(取自评论中的dyp建议):
short s = 1, t = 2 ;
auto x = s + t ;
Run Code Online (Sandbox Code Playgroud)
x将具有int类型.
这可能是一个愚蠢的问题,但有人可以请为C++ 11和C11提供标准参考:
是char默认升为int?
这里有一点背景:C和C++都有默认参数提升的概念(C++ 11:5.2.2/7; C11:6.5.2.2/6).这需要在以下调用中提升参数:
void f(int, ...);
float a = 1; short int b = 2; char c = 'x';
f(0, a, b, c);
Run Code Online (Sandbox Code Playgroud)
对于函数调用,a将转换为double并b转换为int.但是会发生什么c?我一直都认为这char也得到提升int,但我无法在标准中找到相关的陈述.
我有一个简单的程序.请注意,我使用的是无符号的固定宽度整数1字节.
#include <cstdint>
#include <iostream>
#include <limits>
int main()
{
uint8_t x = 12;
std::cout << (x << 1) << '\n';
std::cout << ~x;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的输出如下.
24
-13
Run Code Online (Sandbox Code Playgroud)
我测试了更大的数字,操作员<<总是给我正数,而操作员~总是给我负数.我然后使用sizeof()并发现......
当我使用左移位运算符(
<<)时,我收到一个无符号的4字节整数.当我使用bitwise not运算符(
~)时,我收到一个带符号的4字节整数.
似乎bitwise not运算符(~)像算术运算符一样执行有符号整数提升.但是,左移运算符(<<)似乎提升为无符号整数.
我觉得有必要知道编译器什么时候改变我背后的东西.如果我在分析中是正确的,那么所有按位运算符都会提升为4字节整数吗?为什么一些签名和一些未签名?我很困惑!
编辑:我总是得到肯定或总是得到负值的假设是错误的.但是由于错误,我理解真正发生的事情,这要归功于下面的重要答案.
c++ bitwise-operators integer-promotion unsigned-integer signed-integer
类似于Bitshift和整数提升的问题?,我在使用左位移时有一个关于整数提升的问题.
unsigned int test(void)
{
unsigned char value8;
unsigned int result;
value8 = 0x12;
result = value8 << 8;
return result;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,value8首先会提升为unsiged int还是具体实现?
6.5.7按位移位运算符... 3 Sematics ...
对每个操作数执行整数提升.结果的类型是提升的左操作数的类型.如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义.
它表示"整数促销是在每个操作数上执行的".,但这里的促销规则是什么?
我认为它应该是convert to int if lesser rank than int,但我找不到它.
我问这个,因为一个编译器(Renesas nc30wa)没有提升为int,所以我的样本结果总是0.
在这个平台上,char是8位宽和16位.
因此,如果我理解得很好,整体推广提供:char, wchar_t, bool, enum, short类型总是被转换为int(或unsigned int).然后,如果表达式中有不同的类型,则将应用进一步的转换.
我理解得这么好吗?
如果是,那么我的问题是:它为什么好?为什么?不要变得char/wchar_t/bool/enum/short不必要吗?我的意思是例如:
char c1;
char c2;
c1 = c2;
Run Code Online (Sandbox Code Playgroud)
正如我之前所描述的,charALWAYS被转换为int,所以在这种情况下自动转换后,这看起来像这样:
int c1;
int c2;
c1 = c2;
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么这样好,如果我知道那种char类型足以满足我的需要.
我最近在写一些实际上应该测试其他代码的代码,但偶然发现了一个令人惊讶的整数提升案例。这是最小的测试用例:
#include <cstdint>
#include <limits>
int main()
{
std::uint8_t a, b;
a = std::numeric_limits<std::uint8_t>::max();
b = a;
a = a + 1;
if (a != b + 1)
return 1;
else
return 0;
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,该程序返回1。一些调试和预感表明,b + 1在条件a + 1语句中实际上返回了256,而在赋值操作中产生了预期值0。
C ++ 17草案的第8.10.6节(关于等式/不等号运算符)指出:
如果两个操作数均为算术或枚举类型,则对两个操作数执行常规的算术转换;如果指定的关系为真,则每个运算符都将产生true;如果指定的关系为false,则每个运算符应产生false。
什么是“通常的算术转换”,在标准中它们在哪里定义?我的猜测是,它们隐式地将较小的整数提升为某些运算符int或unsigned int为某些运算符提升(这也得到以下事实的支持:用产生的结果替换std::uint8_t为unsigned int0,而且赋值运算符缺少“常规算术转换”子句)。