Doubts about "int" fragrance operations

I have doubts about the "int" tastes (unsigned int, long int, long long int).

When we perform some operations (*, /, +, -) between an int and its flavorings (say, long int) on a 32-bit system and a 64-bit system, this is an implicit type process for "int"

eg: -

int x; long long int y = 2000;

x = y; (Higher is assigned a lower level of data truncation) I expect the compiler to give a warning for this. But I do not receive such a warning. This is due to an implicit cast of type "x" here. I am using gcc with the -Wall option. Whether the behavior will change for 32-bit and 64-bit.

Thanks Arpit

+4
source share
5 answers

-Wall does not activate all possible warnings. -Wextra allows other warnings. In any case, what you are doing is a completely “legitimate” operation, and since the compiler cannot always know at compile time the value of the binding, which can be “truncated”, it is normal that it does not warn: the programmer should already be aware that a "large" integer cannot fit into a "small" integer, so this usually depends on the programmer. If you think your program is not written consciously, add -Wconversion .

+7
source

Casting without an explicit cast operator is completely legal in C, but it can have undefined behavior. In your case, int x; is signed, so if you try to store a value in it outside the int range, your program has undefined behavior. On the other hand, if x was declared as unsigned x; , the behavior is correctly defined; casting is carried out by decreasing modulo UINT_MAX+1 .

As for arithmetic, when you do arithmetic between integers of different types, the type of "smaller" advances to the "larger" type before arithmetic. The compiler is free to optimize this ad if it does not affect the results, which leads to idioms such as casting a 32-bit integer to 64 bits before multiplication to get the full 64-bit result. Promotion becomes a bit confusing and can have unexpected results when mixing values ​​under a sign and an unsigned one. You must watch it if you want to know, because it is difficult to explain informally.

+3
source

If you're worried, you can include <stdint.h> and use types with a specific length, such as uint16_t for a 16-bit unsigned integer.

+2
source

Your code works fine (as others have said). If you want to program in a portable way, in most cases you should not use the bare types C int , long or unsigned int , but types that say a little better what you plan to do with it.

For example, size_t is always used for array indices. Regardless of whether you are on a 32 or 64-bit system, this will be the right type. Or, if you want to take an integer of the maximum width on the platform, you get to use intmax_t or uintmax_t .

+2
source

See http://gcc.gnu.org/ml/gcc-help/2003-06/msg00086.html - the code is great for C / C ++.

You can look at static analysis tools (sparse, llvm, etc.) to check this type of truncation.

+1
source

Source: https://habr.com/ru/post/1315484/


All Articles