我对“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
答案 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类型int
,long
或unsigned int
,而是可以更好地说明您计划执行的操作的类型用它。
对于数组索引,请始终使用size_t
。无论您使用的是32位还是64位系统,这都是正确的类型。或者,如果您想要在平台上使用最大宽度的整数,那么您将使用intmax_t
或uintmax_t
。
答案 4 :(得分:1)
参见http://gcc.gnu.org/ml/gcc-help/2003-06/msg00086.html - 代码完全有效的C / C ++。
您可能希望查看静态分析工具(稀疏,llvm等)以检查此类截断。