BuckFilledPlatypus
BuckFilledPlatypus

Reputation: 2178

Why or why not should I use 'UL' to specify unsigned long?

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

Answers (7)

Brian Hinkle
Brian Hinkle

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

schanq
schanq

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

Ran.CohenTawil
Ran.CohenTawil

Reputation: 61

When you feel obligated to write down the type of constant (even when not absolutely necessary) you make sure:

  1. That you always consider how the compiler will translate this constant into bits
  2. Who ever reads your code will always know how you thought the constant looks like and that you taken it into consideration (even you, when you rescan the code)
  3. You don't spend time if thoughts whether you need to write the 'U'/'UL' or don't need to write it

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

Khaled Alshaya
Khaled Alshaya

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

Brian Neal
Brian Neal

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

Loki Astari
Loki Astari

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

Sam Harwell
Sam Harwell

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++):

  • Calling a generic method (template in C++), where the parameter types are implied and you want to make sure and call the one with an unsigned long type. This happens reasonably often, including this one recently:
    Tuple<ulong, ulong> = Tuple.Create(someUlongVariable, 0UL);
    where without the UL it returns Tuple<ulong, int> and won't compile.
  • Implicit variable declarations using the 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

Related Questions