char a;
char b;
char c;
a = b + c;
a = (char)((int)b+(int)c);
在第一行中,它隐含了从char
到int
的转换。在第二行,它是明确的。编译器生成的二进制文件有区别吗?
请从嵌入式系统的角度考虑这个问题。
答案 0 :(得分:5)
使用我的编译器,它会生成两次完全相同的程序集:
4: 0f b6 55 ff movzbl -0x1(%rbp),%edx
8: 0f b6 45 fe movzbl -0x2(%rbp),%eax
c: 01 d0 add %edx,%eax
e: 88 45 fd mov %al,-0x3(%rbp)
11: 0f b6 55 ff movzbl -0x1(%rbp),%edx
15: 0f b6 45 fe movzbl -0x2(%rbp),%eax
19: 01 d0 add %edx,%eax
1b: 88 45 fd mov %al,-0x3(%rbp)
如您所见,这是AMD64程序集(由GCC 4.6.2制作)。唯一可以确定的方法是为目标平台编译它并检查程序集。
答案 1 :(得分:4)
我对该标准的阅读表明,这取决于实现和优化器。
第5.1.2.3节,第10部分:
示例2执行片段
char c1, c2;
/* ... */
c1 = c1 + c2;
''整数提升''要求抽象机将每个变量的值提升为int大小,然后添加两个整数并截断总和。如果可以在没有溢出的情况下添加两个字符,或者通过静默溢出来生成正确的结果,则实际执行只需要产生相同的结果,可能省略促销。
我的理解是标准允许编译器决定是否可以使用8位加法,只要结果不能与添加整数和转换为字符区分开来。
注意回到我在嵌入式世界(九十年代中期)的日子,我们用于8位平台的C编译器,Whitesmith编译器用于68HC11,产生了“简单的“8位加法指令,用于添加两个char
s。找出你的fujitsu系统中发生的事情的唯一方法是编译到汇编并自己检查。
答案 2 :(得分:2)
根据C标准,结果必须相同,嵌入与否。
答案 3 :(得分:1)
表达式语句(1)和(2)都是等价的。
char a;
char b;
char c;
a = b + c; // (1)
a = (char)((int)b+(int)c); // (2)
根据通常的算术转换规则,b
和c
都转换为int
(整数提升)。然后b
+ c
被赋值运算符的语义转换为char
。
加法运算符:
(C99,6.5.6p4)“如果两个操作数都有算术类型,则对它们执行通常的算术转换。”
简单分配:
(C99,6.5.16.1p2赋值)“在简单赋值(=)中,右操作数的值被转换为赋值表达式的类型,并替换存储在左操作数”“指定的对象中的值。
整数促销:
(C99,6.3.1.1p2)“如果int可以表示原始类型的所有值,则该值将转换为int;否则,它将转换为unsigned int。这些称为整数提升。”