0

Reference: Suffix in Integer Constants

unsigned long long y = 1 << 33;

Results in warning:

left shift count >= width of type [-Wshift-count-overflow]

Two Questions need to be cleared from the above context:

  1. unsigned long long type has 64-bit, why cant we do left shift in it?
  2. how shifting works in int constants('1')?
  • 3
    Think of it this way: the compiler looks at the expression `1<<33` on its own first. Only once that is evaluated it looks at what it needs to do with the result. The type of the left hand sign of the assignment doesn't come into play until it is "too late" in this case. – Mat Nov 05 '20 at 08:12
  • If you want to reference another question, please make sure to *link* to that question. Please read [the editing help](https://stackoverflow.com/editing-help) to learn how to create links. – Some programmer dude Nov 05 '20 at 08:13

1 Answers1

3

In C language, 1 is an int which is 32 bits on most platforms. When you try to shift it 33 bits before storing its value in an unsigned long long, that's not going to end well. You can fix this in 2 ways:

  • Use 1ULL instead, which is an unsigned long long constant:
unsigned long long y = 1ULL << 33;
  • Assign the value, then shift it:
unsigned long long y = 1;
y <<= 33;

Both are valid, but I'd suggest the first one since it's shorter and you can make y const.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • And why the value '1' is considered as a integer constant by default. If so, if overwrite any value, it is changing. Constants could not be changed? – sat.learner Nov 05 '20 at 09:51
  • @sat.learner because the standard says so. Integer literals without any suffices that are small enough to fit into an `int` have the type `int`. If you want them to have any other type, use appropriate suffices like `ULL`. – Aykhan Hagverdili Nov 05 '20 at 09:53
  • Can we overwrite the integer constant? After we chosen the right constant type. – sat.learner Nov 05 '20 at 09:58
  • @sat.learner I am not sure what you mean by "overwrite". Do you want `1` to be an `unsigned long long` without `ULL`? – Aykhan Hagverdili Nov 05 '20 at 09:59
  • If this line compiled: unsigned long long y = 1ULL << 33; It's means that, y has a constant integer value. We can't able to change it. How the shift operator works in a constant value. It will not work(considering the value as constant). How compiler reads it as int value. ( If we are telling that it's a constant value. Then how we relate this with using 'const': const unsigned long long y =1ULL.) – sat.learner Nov 05 '20 at 10:12
  • @sat.learner It's not because `1` is const. It's because `1` is a literal. `const unsigned long long y = 1;` has the type `unsigned long long`. – Aykhan Hagverdili Nov 05 '20 at 10:18
  • 2
    @AyxanHaqverdili Detail: C calls `1` a _constant_ , not a literal nor a `const`. C specifies 2 literals: string and complex, not any others. – chux - Reinstate Monica Mar 18 '21 at 02:52
  • @chux-ReinstateMonica hmm, interesting. It's called [Integer literal](https://en.cppreference.com/w/cpp/language/integer_literal) for C++ and [Integer constant](https://en.cppreference.com/w/c/language/integer_constant) for C. – Aykhan Hagverdili Mar 18 '21 at 07:09
  • 1
    In C, the address can be taken of a literal, but not a constant. `char (*a)[] = &"hello"; int *b = &(int){42};` vs. `int *c_invalid = &123;`. – chux - Reinstate Monica Mar 18 '21 at 10:45