Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when I assign long int to int in C?

In a recent homework assignment I've been told to use long variable to store a result, since it may be a big number.

I decided to check will it really matter for me, on my system (intel core i5/64-bit windows 7/gnu gcc compiler) and found out that the following code:

printf("sizeof(char) => %d\n", sizeof(char)); printf("sizeof(short) => %d\n", sizeof(short)); printf("sizeof(short int) => %d\n", sizeof(short int)); printf("sizeof(int) => %d\n", sizeof(int)); printf("sizeof(long) => %d\n", sizeof(long)); printf("sizeof(long int) => %d\n", sizeof(long int)); printf("sizeof(long long) => %d\n", sizeof(long long)); printf("sizeof(long long int) => %d\n", sizeof(long long int)); 

produces the following output:

sizeof(char) => 1 sizeof(short) => 2 sizeof(short int) => 2 sizeof(int) => 4 sizeof(long) => 4 sizeof(long int) => 4 sizeof(long long) => 8 sizeof(long long int) => 8 

In other words, on my system, int and long are the same, and whatever will be too big for int to hold, will be too big for long to hold as well.

The homework assignment itself is not the issue here. I wonder how, on a system where int < long, should I assign an int to long?

I'm aware to the fact that there are numerous closely related questions on this subject, but I feel that the answers within these do not provide me with the complete understanding of what will or may happen in the process.

Basically I'm trying to figure out the following:

  1. Should I cast long to int before the assignment, or since long is not a different data type, but merely a modifier, it will be considered unharmful to assign directly?
  2. What happens on systems where long > int? Will the result be undefined (or unpredictable) or it will cause the extra parts of the variable to be omitted?
  3. How does the casting from long to int works in C?
  4. How does the assignment from long to int works in C when I don't use casting?
like image 793
Khaloymes Avatar asked Nov 30 '12 20:11

Khaloymes


People also ask

What happens if you add a long to an int?

Yes, you can add a long and an int just fine, and you'll end up with a long . The int undergoes a widening primitive conversion, as described in the Java Language Specification, specifically JLS8, §5.1. 2 .

Can we assign long to int?

You can cast a long to int so long as the number is less than 2147483647 without an error.

Can we type cast long to int in C?

In terms of converting a ( signed ) long long datatype to an unsigned int in C and C++, you can simply cast the data between them: int main()

Is int same as long int in C?

"a long in C/C++ is the same length as an int." Not always. The C++ standard specifies that an int be the "natural" size for the processor, which may not always be as big as a long . The standard also guarantees that a long is at least as long as an int , so the fact that they are equal sizes are not always guaranteed.


1 Answers

The language guarantees that int is at least 16 bits, long is at least 32 bits, and long can represent at least all the values that int can represent.

If you assign a long value to an int object, it will be implicitly converted. There's no need for an explicit cast; it would merely specify the same conversion that's going to happen anyway.

On your system, where int and long happen to have the same size and range, the conversion is trivial; it simply copies the value.

On a system where long is wider than int, if the value won't fit in an int, then the result of the conversion is implementation-defined. (Or, starting in C99, it can raise an implementation-defined signal, but I don't know of any compilers that actually do that.) What typically happens is that the high-order bits are discarded, but you shouldn't depend on that. (The rules are different for unsigned types; the result of converting a signed or unsigned integer to an unsigned type is well defined.)

If you need to safely assign a long value to an int object, you can check that it will fit before doing the assignment:

#include <limits.h> /* for INT_MIN, INT_MAX */  /* ... */  int i; long li = /* whatever */  if (li >= INT_MIN && li <= INT_MAX) {     i = li; } else {     /* do something else? */ } 

The details of "something else" are going to depend on what you want to do.

One correction: int and long are always distinct types, even if they happen to have the same size and representation. Arithmetic types are freely convertible, so this often doesn't make any difference, but for example int* and long* are distinct and incompatible types; you can't assign a long* to an int*, or vice versa, without an explicit (and potentially dangerous) cast.

And if you find yourself needing to convert a long value to int, the first thing you should do is reconsider your code's design. Sometimes such conversions are necessary, but more often they're a sign that the int to which you're assigning should have been defined as a long in the first place.

like image 172
Keith Thompson Avatar answered Oct 05 '22 07:10

Keith Thompson