Reputation: 2178
ulong foo = 0;
ulong bar = 0UL;//this seems redundant and unnecessary. but I see it a lot.
I also see this in referencing the first element of arrays a good amount
blah = arr[0UL];//this seems silly since I don't expect the compiler to magically
//turn '0' into a signed value
Can someone provide some insight to why I need 'UL' throughout to specify specifically that this is an unsigned long?
Upvotes: 17
Views: 51528
Reputation: 51
I feel like a lot of answers are missing a huge reason why the suffix is helpful. When using an unsigned long as an r-value it can make code look cleaner.
Let's say you're in a situation where you need to check if the 6th bit from a bitfield is on. The code looks very clean when using the suffix....
bool sixthBitIsOn = (bitfield >> 5) & 1ul;
And without using the suffix....
bool sixthBitIsOn = (bitfield >> 5) & static_cast<unsigned long>(1);
As you can see not using the suffix here forces us to perform an ugly-looking inline cast just so we can compare with a positive least significant bit, but the suffix allows us to create an unsigned long as an r-value for quick usage.
Upvotes: 1
Reputation: 934
Sorry, I realize this is a rather old question, but I use this a lot in c++11 code...
ul
, d
, f
are all useful for initialising auto
variables to your intended type, e.g.
auto my_u_long = 0ul;
auto my_float = 0f;
auto my_double = 0d;
Checkout the cpp reference on numeric literals: http://www.cplusplus.com/doc/tutorial/constants/
Upvotes: 5
Reputation: 61
When you feel obligated to write down the type of constant (even when not absolutely necessary) you make sure:
also, several software development standards such as MISRA require you to mention the type of constant no matter what (at least write 'U' if unsigned)
in other words it is believed by some as good practice to write the type of constant because at the worst case you just ignore it and at the best you avoid bugs, avoid a chance different compilers will address your code differently and improve code readability
Upvotes: 2
Reputation: 96889
void f(unsigned int x)
{
//
}
void f(int x)
{
//
}
...
f(3); // f(int x)
f(3u); // f(unsigned int x)
It is just another tool in C++; if you don't need it don't use it!
Upvotes: 30
Reputation: 32399
In the examples you provide it isn't needed. But suffixes are often used in expressions to prevent loss of precision. For example:
unsigned long x = 5UL * ...
You may get a different answer if you left off the UL suffix, say if your system had 16-bit ints and 32-bit longs.
Here is another example inspired by Richard Corden's comments:
unsigned long x = 1UL << 17;
Again, you'd get a different answer if you had 16 or 32-bit integers if you left the suffix off.
The same type of problem will apply with 32 vs 64-bit ints and mixing long and long long in expressions.
Upvotes: 20
Reputation: 264631
Some compiler may emit a warning I suppose.
The author could be doing this to make sure the code has no warnings?
Upvotes: 10
Reputation: 99979
You don't normally need it, and any tolerable editor will have enough assistance to keep things straight. However, the places I use it in C# are (and you'll see these in C++):
unsigned long
type. This happens reasonably often, including this one recently:Tuple<ulong, ulong> = Tuple.Create(someUlongVariable, 0UL);
UL
it returns Tuple<ulong, int>
and won't compile.var
keyword in C# or the auto
keyword coming to C++. This is less common for me because I only use var
to shorten very long declarations, and ulong
is the opposite.Upvotes: 4