the integer literal "UL"
... is not called an "integer literal". That term is not used in C language specification at all, and it risks confusion with "integer constant", of which the whole 1UL
would be an example. Informally, you might call a (whole) integer constant an "integer literal", but not the "UL" part alone. The "UL" by itself can be called a "suffix", and if we draw names from the formal grammar in the language spec then we could call it an "integer suffix" more specifically.
IMHO, the integer literal "UL" is suppose to suppress unwanted shift, e.g. sign-extending a signed integer may result in multiple bits being set.
The primary purpose of expressing an integer constant with a suffix is to control its data type. 1UL
has type unsigned long int
, whereas unsuffixed 1
has type int
.
However, if the case is, doing logical left shift only, as shown above, do we still need the integer literal?
In a bitwise shift operation, the type of the left operand is the type of the result, and it can affect the value of the result. It can also affect whether evaluating the expression even has defined behavior at all.
In the case of the particular macro you present, whether it is important to use 1UL
instead of just 1
depends on how the macro is used. But there are wholly reasonable uses for which using 1UL
produces the desired effect but just 1
does not.
As a left shift won't cause un-intended behavior,
Did you mean undefined behavior? A left shift of a value of a signed type (even a positive one) absolutely can have undefined behavior as far as C is concerned. And in cases where the behavior is undefined, you are totally unjustified in assuming the result will be what you expect or intend.
I can't figure what is its purpose then.
Even if we ignore questions around signedness, if int
and long int
are different size, as often they are, then 1U << n
may yield a different, well defined result than 1UL
does. In such a case, it is unreasonable to expect 1 << n
to evaluate to the same result that 1UL << n
does, undefined behavior notwithstanding.
1UL
instead of simply1
? TheUL
stands forunsigned long
and so1UL
is an integer expression of typeunsigned long
, whereas1
would just beint
. – Keratoplasty"abc"
and123
are literals because you know what their values are just from looking at them. That is not true of an enum memberfoo
, which is also an integer constant but is not a literal. The C standard would have been to use the term “literal” for all the literal constants, instead of just string literals, and that is how OP is using it. – Akira