2010-07-13 46 views
4

我对“int”风味(无符号整数,长整型,长整型长整型)有以下怀疑。有关“int”风味操作的疑问

当我们做一些操作(*,/,+, - )int和它的味道之间(可以说长整型) 在32位系统和64位系统是隐式类型转换发生了“INT”

为例如: -

int x; long long int y = 2000;

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

由于 Arpit

+0

下面有非常好的答案,也许你可以标记为正确的? – alecco 2010-07-15 16:19:01

回答

7

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

+0

是的,除了其他事情之外,-WConversion会告诉你何时将更大类型隐式转换为更小类型。 gcc的Apple分支也有'-Whorten-64-to-32'。 – JeremyP 2010-07-13 12:23:39

+0

+1 for -Wconversion。 – Dummy00001 2010-07-13 12:23:57

2

如果担心,可以包括<stdint.h>和利用类型具有限定的长度,如uint16_t为一个16位无符号整数。

1

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

您可能想要查看静态分析工具(稀疏,llvm等)来检查此类型的截断。

+0

嗯,海湾合作委员会的人有时并不是真正有帮助的... /我想到海湾合作委员会和严格的别名规则。 /我不寒而栗。 – Dummy00001 2010-07-13 12:21:59

3

没有显式类型转换运算符的铸造在C中是完全合法的,但可能有未定义的行为。在你的情况下,int x;是签名的,所以如果你尝试在int范围外存储一个值,你的程序就会有未定义的行为。另一方面,如果x被声明为unsigned x;,则行为是明确的;通过减模UINT_MAX+1进行施放。对于算术,当你在不同类型的整数之间进行算术运算时,在算术之前'较小'类型被提升为'较大'类型。如果编译器不影响结果,那么编译器可以自由优化此升级过程,这会导致在将乘以获得完整的64位结果之前将32位整数转换为64位的习惯用法。促销活动有点混乱,并且在签名和无符号值混合使用时可能会产生意想不到的结果。如果你想知道,你应该查看它,因为很难非正式解释。

+0

不错的答案,但我倾向于避免“隐式投射”。按定义进行投射是明确的。转换是隐含的或显式的。 – 2010-07-13 06:10:27

+1

新的措辞更好吗? – 2010-07-13 06:28:40

+0

@R:我不太确定。这里的问题(如你在答案中注意到的)是涉及的类型,投射和转换根本不会出现在图片中。无论是演员还是转换,都会存在相同的未定义行为。给定'长x = 200000; int i = x; int j =(int)x;','i'和'j'的赋值都有一个(潜在的)问题。 – 2010-07-16 00:43:29

2

您的代码完全有效(正如其他人所说的)。如果您想在大多数情况下以便携式方式进行编程,则不应使用裸露的C类型int,longunsigned int,但可以更好地说明您打算如何处理它。

对于数组索引,总是使用size_t。无论你是否在32位或64位系统上,这将是正确的类型。或者,如果您想在平台上采用最大宽度的整数,那么您恰好使用intmax_tuintmax_t