关于“int”口味的操作存在疑问

时间:2010-07-13 05:43:21

标签: c linux gcc gcc-warning

我对“int”风格有疑问(unsigned int,long int,long long int)。

当我们在int和它的味道之间做一些操作(*,/,+, - )时(比如说long int) 在32位系统和64位系统中是“int”的隐式类型转换

例如: -

int x; long long int y = 2000;

x = y; (更高的分配可能会发生较低的一次数据截断) 我期待编译器为此发出警告但我没有收到任何此类警告。 这是由于隐式类型转换在这里发生的“x”。 我正在使用gcc和-Wall选项。行为是否会因32位和64位而改变。

由于 Arpit

5 个答案:

答案 0 :(得分:7)

-Wall不会激活所有可能的警告。 -Wextra启用其他警告。无论如何,你所做的是一个完美的“合法”操作,因为编译器不能总是在编译时知道可能被“截断”的数据的值,所以它没有警告:程序员应该已经知道事实上,“大”整数不能适合“小”整数,因此通常由程序员决定。如果您认为您的程序是在不了解此程序的情况下编写的,请添加-Wconversion

答案 1 :(得分:3)

没有显式类型转换运算符的转换在C中完全合法,但可能具有未定义的行为。在您的情况下,int x;已签名,因此如果您尝试在其中存储超出int范围的值,则您的程序具有未定义的行为。另一方面,如果x被声明为unsigned x;,则行为是明确定义的;施法是通过减少模UINT_MAX+1

对于算术运算,当您在不同类型的整数之间执行算术运算时,“较小”类型在算术运算之前被提升为“较大”类型。如果它不影响结果,编译器可以自由地优化这个促销,这导致在乘以获得完整的64位结果之前将32位整数转换为64位的习惯用法。促销变得有点混乱,并且当签名和无符号值混合时可能会产生意外结果。你应该仔细查看,因为很难非正式地解释。

答案 2 :(得分:2)

如果您感到担心,可以包含<stdint.h>并使用定义长度的类型,例如uint16_t表示16位无符号整数。

答案 3 :(得分:2)

您的代码完全有效(正如其他人已经说过的那样)。如果您想在大多数情况下以便携方式进行编程,则不应使用裸C类型intlongunsigned int,而是可以更好地说明您计划执行的操作的类型用它。

对于数组索引,请始终使用size_t。无论您使用的是32位还是64位系统,这都是正确的类型。或者,如果您想要在平台上使用最大宽度的整数,那么您将使用intmax_tuintmax_t

答案 4 :(得分:1)

参见http://gcc.gnu.org/ml/gcc-help/2003-06/msg00086.html - 代码完全有效的C / C ++。

您可能希望查看静态分析工具(稀疏,llvm等)以检查此类截断。