4

我对“int”风格(unsigned int、long int、long long int)有以下疑问。

在 32 位系统和 64 位系统中,当我们在 int 及其风格(比如说 long int)之间进行一些操作(*、/、+、-)时,“int”会发生隐式类型转换

例如 :-

诠释 x ; long long int y = 2000;

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

谢谢阿皮特

4

5 回答 5

7

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

于 2010-07-13T05:55:12.660 回答
3

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

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

于 2010-07-13T05:55:18.407 回答
2

您的代码完全有效(正如其他人已经说过的那样)。如果您想在大多数情况下以可移植的方式进行编程,则不应使用裸 C 类型intlong或者使用能unsigned int更好地说明您打算用它做什么的类型。

例如,对于数组的索引,使用 always size_t。无论您使用的是 32 位还是 64 位系统,这都是正确的类型。或者,如果你想在你碰巧登陆的平台上取最大宽度的整数,intmax_t或者uintmax_t.

于 2010-07-13T06:08:11.893 回答
2

如果您担心,您可以包含<stdint.h>并使用具有定义长度的类型,例如uint16_t16 位无符号整数。

于 2010-07-13T05:46:04.323 回答
1

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

您可能需要查看静态分析工具(稀疏、llvm 等)来检查这种类型的截断。

于 2010-07-13T05:54:30.983 回答