Then why do people use the (1 << 7) version?

It is a form of documentation, it is not a magic number but 2^7 (two to the seventh power) which is meaningful to whomever wrote the code. A modern optimizing compiler should generate the exact same code for both examples and so there is no cost to using this form and there is a benefit of adding context.

Using godbolt we can verify this is indeed the case, at least for several versions of gcc , clang and icc . Using a simple example with side effects to ensure that the code is not totally optimized away:

#include <stdio.h> void forLoopShift() { for(int i = 0; i < (1 << 7); i++) { printf("%d ", i ) ; } } void forLoopNoShift() { for(int i = 0; i < 128; i++) { printf("%d ", i ) ; } }

For the relevant part of the code we can see they both generate the following see it live:

cmpl $128, %ebx

What we have is an integer constant expression as defined in the draft C11 standard section 6.6 Constant expressions which says:

An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants,[...]

and:

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.115)

and we can see that a constant expression is allowed to be evaluated during translation: