对“int”操作的疑问口味
我对“int”风格(unsigned int、long int、long long int)有以下疑问。
当我们在 int 和它的类型(比如 long int)之间进行一些操作(*、/、+、-)时 在 32 位系统和 64 位系统中,“int”会发生隐式类型转换,
例如:-
int x ; 长整型 y = 2000;
x = y ; (将较高的一位分配给较低的一位可能会发生数据截断) 我希望编译器对此发出警告,但我没有收到任何此类警告。 这是因为这里的“x”发生了隐式类型转换吗? 我正在使用 gcc 和 -Wall 选项。 32 位和 64 位的行为是否会发生变化。
谢谢 阿尔皮特
I am having following doubt regarding "int" flavors (unsigned int, long int, long long int).
When we do some operations(* , /, + , -) between int and its flavors (lets say long int)
in 32bit system and 64bit system is the implicit typecast happen for "int"
for example :-
int x ;
long long int y = 2000;
x = y ; (Higher is assigned to lower one data truncation may happen)
I am expecting compiler to give warning for this But I am not getting any such warning.
Is this due to implicit typecast happen for "x" here.
I am using gcc with -Wall option. Is the behavior will change for 32bit and 64bit.
Thanks
Arpit
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
-Wall
不会激活所有可能的警告。-Wextra
启用其他警告。不管怎样,你所做的是一个完全“合法”的操作,并且由于编译器不能总是在编译时知道可能被“截断”的数据的值,所以它不会发出警告是可以的:程序员应该已经意识到了事实上,“大”整数无法适合“小”整数,因此通常由程序员决定。如果您认为您的程序是在没有意识到这一点的情况下编写的,请添加-Wconversion
。-Wall
does not activate all possible warnings.-Wextra
enables other warnings. Anyway, what you do is a perfectly "legal" operation and since the compiler can't always know at compile-time the value of the datum that could be "truncated", it is ok it does not warn: programmer should be already aware of the fact that a "large" integer could not fit into a "small" integer, so it is up to the programmer usually. If you think your program is written in not-awareness of this, add-Wconversion
.没有显式类型转换运算符的转换在 C 中是完全合法的,但可能具有未定义的行为。在您的情况下,
int x;
是有符号的,因此如果您尝试在其中存储超出int
范围的值,您的程序将具有未定义的行为。另一方面,如果x
被声明为unsigned x;
,则行为是明确定义的;强制转换是通过对UINT_MAX+1
取模进行缩减来实现的。至于算术,当您在不同类型的整数之间执行算术时,“较小”类型会在算术之前提升为“较大”类型。当然,如果不影响结果,编译器可以自由地优化这种提升,这会导致一些习惯用法,例如在乘法获得完整的 64 位结果之前将 32 位整数转换为 64 位。当有符号值和无符号值混合时,提升会有点混乱,并且可能会产生意想不到的结果。如果您想知道,您应该查一下,因为很难非正式地解释。
Casting without an explicit type cast operator is perfectly legal in C, but may have undefined behavior. In your case,
int x;
is signed, so if you try to store a value in it that's outside the range ofint
, your program has undefined behavior. On the other hand, ifx
were declared asunsigned x;
the behavior is well-defined; cast is via reduction moduloUINT_MAX+1
.As for arithmetic, when you perform arithmetic between integers of different types, the 'smaller' type is promoted to the 'larger' type prior to the arithmetic. The compiler is free to optimize out this promotion of course if it does not affect the results, which leads to idioms like casting a 32bit integer to 64bit before multiplying to get a full 64bit result. Promotion gets a bit confusing and can have unexpected results when signed and unsigned values are mixed. You should look it up if you care to know since it's hard to explain informally.
如果您担心,可以包含
并使用具有定义长度的类型,例如用于 16 位无符号整数的uint16_t
。If you are worried, you can include
<stdint.h>
and use types with defined lengths, such asuint16_t
for a 16-bit unsigned integer.您的代码完全有效(正如其他人已经说过的)。如果您想在大多数情况下以可移植的方式进行编程,则不应使用裸 C 类型
int
、long
或unsigned int
,而应使用以下类型更好地告诉你你打算用它做什么。例如,对于数组的索引,始终使用
size_t
。无论您使用的是 32 位还是 64 位系统,这都是正确的类型。或者,如果您想获取平台上最大宽度的整数,您碰巧会使用intmax_t
或uintmax_t
。Your code is perfectly valid (as already said by others). If you want to program in a portable way in most cases you should not use the bare C types
int
,long
orunsigned int
but types that tell a bit better what you are planing to do with it.E.g for indices of arrays use always
size_t
. Regardless on whether or not you are on a 32 or 64 bit system this will be the right type. Or if you want to take the integer of maximal width on the platform you happen to land on useintmax_t
oruintmax_t
.请参阅 http://gcc.gnu.org/ml/gcc -help/2003-06/msg00086.html——代码是完全有效的C/C++。
您可能需要查看静态分析工具(sparse、llvm 等)来检查这种类型的截断。
See http://gcc.gnu.org/ml/gcc-help/2003-06/msg00086.html -- the code is perfectly valid C/C++.
You might want to look at static analysis tools (sparse, llvm, etc.) to check for this type of truncation.