ULL suffix on a numeric literal
From the gcc
manual:
ISO C99 supports data types for integers that are at least 64 bits wide ( . . . ) . To make an integer constant of type
long long int
, add the suffixLL
to the integer. To make an integer constant of typeunsigned long long int
, add the suffixULL
to the integer.
These suffixes have also been added to C++ in C++11, and were already supported long long (pun intended) before that as compiler extensions.
why we found ULL in the end of patterns used for memory testing?
In case of your code snippet it is only for self-commenting the code.
The suffux llu
is used for explicit specifying that an integer constant has the type unsigned long long
.
However when a constant is presented in the hexadecimal notation the suffix can be omitted because the compiler itself determines the type of the constant. That is (The C Standard, 6.4.4.1 Integer constants)
5 The type of an integer constant is the first of the corresponding
list in which its value can be represented.
And for hexadecimal integer constants
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
what is the reason for explicitly declaring L or UL for long values
When a suffix L
or UL
is not used, the compiler uses the first type that can contain the constant from a list (see details in C99 standard, clause 6.4.4:5. For a decimal constant, the list is int
, long int
, long long int
).
As a consequence, most of the times, it is not necessary to use the suffix. It does not change the meaning of the program. It does not change the meaning of your example initialization of x
for most architectures, although it would if you had chosen a number that could not be represented as a long long
. See also codebauer's answer for an example where the U
part of the suffix is necessary.
There are a couple of circumstances when the programmer may want to set the type of the constant explicitly. One example is when using a variadic function:
printf("%lld", 1LL); // correct, because 1LL has type long long
printf("%lld", 1); // undefined behavior, because 1 has type int
A common reason to use a suffix is ensuring that the result of a computation doesn't overflow. Two examples are:
long x = 10000L * 4096L;
unsigned long long y = 1ULL << 36;
In both examples, without suffixes, the constants would have type int
and the computation would be made as int
. In each example this incurs a risk of overflow. Using the suffixes means that the computation will be done in a larger type instead, which has sufficient range for the result.
As Lightness Races in Orbit puts it, the litteral's suffix comes before the assignment. In the two examples above, simply declaring x
as long
and y
as unsigned long long
is not enough to prevent the overflow in the computation of the expressions assigned to them.
Another example is the comparison x < 12U
where variable x
has type int
. Without the U
suffix, the compiler types the constant 12
as an int
, and the comparison is therefore a comparison of signed ints.
int x = -3;
printf("%d\n", x < 12); // prints 1 because it's true that -3 < 12
With the U
suffix, the comparison becomes a comparison of unsigned ints. “Usual arithmetic conversions” mean that -3 is converted to a large unsigned int:
printf("%d\n", x < 12U); // prints 0 because (unsigned int)-3 is large
In fact, the type of a constant may even change the result of an arithmetic computation, again because of the way “usual arithmetic conversions” work.
Note that, for decimal constants, the list of types suggested by C99 does not contain unsigned long long
. In C90, the list ended with the largest standardized unsigned integer type at the time (which was unsigned long
). A consequence was that the meaning of some programs was changed by adding the standard type long long
to C99: the same constant that was typed as unsigned long
in C90 could now be typed as a signed long long
instead. I believe this is the reason why in C99, it was decided not to have unsigned long long
in the list of types for decimal constants.
See this and this blog posts for an example.
C literal suffix U, UL problems
A decimal number like -1,1,2,12345678, etc. without any suffix will get the smallest type it will fit, starting with int
, long
, long long
.
An octal or hex number like 0, 0123, 0x123, 0X123 without any suffix will get the smallest type it will fit, starting with int
, unsigned
, long
, unsigned long
, long long
, unsigned long long
.
The following is a potential problem should AAR_INTENSET_NOTRESOLVED_Pos
exceed 31. Note: unsigned long
must be at least 32 bits. It would result in 0 ** if unsigned long
was 32 bits, but non-zero if longer.
(0x1UL << AAR_INTENSET_NOTRESOLVED_Pos)
The following is a similar potential problem should AAR_INTENSET_NOTRESOLVED_Pos
exceed 15. 0x1
is an unsigned
, which must only be at least 16 bits. Also if unsigned/int
is 16 bits, the minimum, 0x1
will be int
. So without explicitly using U
, 0x1
could be a problem if AAR_INTENSET_NOTRESOLVED_Pos == 15
. [@Matt McNabb]
(0x1 << AAR_INTENSET_NOTRESOLVED_Pos)
Bitwise shift operators
"The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined." C11dr §6.5.7 3
Machine width is not the key issue. An 8bit or 16bit machine could use 16, 32, etc. bit size int
. Again, 16 bit is the minimum size for a compliant C compiler.
[Edit] **
I should have said " It (shifting more than 31 bits) would result in Undefined behavior, UB, if unsigned long
was 32 bits."
What do 0LL or 0x0UL mean?
These are constants in C and C++. The suffix LL
means the constant is of type long long
, and UL
means unsigned long
.
In general, each L
or l
represents a long
and each U
or u
represents an unsigned
. So, e.g.
1uLL
means the constant 1 with type unsigned long long
.
This also applies to floating point numbers:
1.0f // of type 'float'
1.0 // of type 'double'
1.0L // of type 'long double'
and strings and characters, but they are prefixes:
'A' // of type 'char'
L'A' // of type 'wchar_t'
u'A' // of type 'char16_t' (C++0x only)
U'A' // of type 'char32_t' (C++0x only)
In C and C++ the integer constants are evaluated using their original type, which can cause bugs due to integer overflow:
long long nanosec_wrong = 1000000000 * 600;
// ^ you'll get '-1295421440' since the constants are of type 'int'
// which is usually only 32-bit long, not big enough to hold the result.
long long nanosec_correct = 1000000000LL * 600;
// ^ you'll correctly get '600000000000' with this
int secs = 600;
long long nanosec_2 = 1000000000LL * secs;
// ^ use the '1000000000LL' to ensure the multiplication is done as 'long long's.
In Google Go, all integers are evaluated as big integers (no truncation happens),
var nanosec_correct int64 = 1000000000 * 600
and there is no "usual arithmetic promotion"
var b int32 = 600
var a int64 = 1000000000 * b
// ^ cannot use 1000000000 * b (type int32) as type int64 in assignment
so the suffixes are not necessary.
Can we assign a unsigned int varaible, 0xFULL literal
It's just a coincidence that it happens to spell out a word. The ULL
suffix means you've got an unsigned long long
literal, and 0xF
or 0x0F
you already know: that's 15, except expressed in hexadecimal.
C++ `long long` variable type
It is a suffix that specifies the type of literal (in this case, integer literals).
You can find out more about this in the C++ standard, specifically in 2.14 - Literals
In your case, the answer lies in the following table (from this very part of the standard) : unsigned long long
.
LLU bad suffix on number
Looking at the standards I have available to me (drafts only, but of reasonably recent versions), both C++ and C define both "ULL" and "LLU" as valid suffixes for an integer literal. This may be a recent change which VS2010 doesn't follow, but I note that VS2012 does the exact same thing (i.e only ULL works).
There is a difference between using a signed and unsigned literal, and that is MSVC's behaviour when you right-shift a signed value. A signed literal will be sign-extended, but an unsigned literal will be padded with zero.
In other words, the following contrived example:
unsigned long long l2 = ~0LL >> 5;
unsigned long long l3 = ~0ULL >> 5;
...will produce two different values under MSVC.
So if your library is expecting defined behaviour by stipulating unsigned values, then converting them to unsigned values will potentially result in undefined behaviour.
In short, I think MSVC is being a bit naughty in only accepting one form of the suffix, but the best fix is to switch where the 'U' appears, and not to remove it entirely.
Related Topics
How to Initialize Std::Vector from C-Style Array
When Using C Headers in C++, Should We Use Functions from Std:: or the Global Namespace
Ull Suffix on a Numeric Literal
What Is the 'Override' Keyword in C++ Used For
Cmake: How to Set Up Source, Library and Cmakelists.Txt Dependencies
How to Initialise Memory With New Operator in C++
C++ [] Array Operator With Multiple Arguments
How to Automatically Convert Strongly Typed Enum into Int
Erasing from a Std::Vector While Doing a For Each
_Builtin_Prefetch, How Much Does It Read
How to Remove an Item from a Stl Vector With a Certain Value
Does Mingw-W64 Support Std::Thread Out of the Box When Using the Win32 Threading Model
Cannot Find or Open the Pdb File in Visual Studio C++ 2010
Why Class Data Members Can't Be Initialized by Direct Initialization Syntax
How to Enable Gdb Pretty Printing For C++ Stl Objects in Eclipse Cdt