tags:

views:

824

answers:

7

42 as unsigned int is well defined as "42U".

unsigned int foo = 42U; // yeah!

How can I write "23" so that it is clear it is an unsigned short int?

unsigned short bar = 23; // booh! not clear!


EDIT so that the meaning of the question is more clear:

template <class T>
void doSomething(T) {
    std::cout << "unknown type" << std::endl;
}

template<>
void doSomething(unsigned int) {
    std::cout << "unsigned int" << std::endl;
}

template<>
void doSomething(unsigned short) {
    std::cout << "unsigned short" << std::endl;
}

int main(int argc, char* argv[])
{
    doSomething(42U);
    doSomething((unsigned short)23); // no other option than a cast?

    return EXIT_SUCCESS;
}
+9  A: 

You can't. Numeric literals cannot have short or unsigned short type.

Of course in order to assign to bar, the value of the literal is implicitly converted to unsigned short. In your first sample code, you could make that conversion explicit with a cast, but I think it's pretty obvious already what conversion will take place. Casting is potentially worse, since with some compilers it will quell any warnings that would be issued if the literal value is outside the range of an unsigned short. Then again, if you want to use such a value for a good reason, then quelling the warnings is good.

In the example in your edit, where it happens to be a template function rather than an overloaded function, you do have an alternative to a cast: do_something<unsigned short>(23). With an overloaded function, you could still avoid a cast with:

void (*f)(unsigned short) = &do_something;
f(23);

... but I don't advise it. If nothing else, this only works if the unsigned short version actually exists, whereas a call with the cast performs the usual overload resolution to find the most compatible version available.

Steve Jessop
A: 

Unfortunately, the only method defined for this is

One or two characters in single quotes ('), preceded by the letter L

According to http://cpp.comsci.us/etymology/literals.html

Which means you would have to represent your number as an ASCII escape sequence:

unsigned short bar = L'\x17';
Tyler McHenry
Your literal will have type `wchar_t`. The source you cite is wrong.
avakar
Thanks for the correction. I'll leave this answer up in case anyone else is misled by that link (which comes up on an obvious google search for this question), as I was.
Tyler McHenry
It's got more problems, such as assuming ASCII. 'A' isn't always 65.
MSalters
+1  A: 

Unfortunately, they can't. But if people just look two words behind the number, they should clearly see it is a short... It's not THAT ambiguous. But it would be nice.

micmoo
It's ambiguous if a method behaves differently for unsigned int and unsigned short and if you pass it as doThings(42U);. Any way other than doThings((unsigned short)23) ?
moala
A: 

If you express the quantity as a 4-digit hex number, the unsigned shortness might be clearer.

unsigned short bar = 0x0017;

bobbymcr
0x0017 as an unsigned short may be clear for the reader, but not for the compiler.
moala
+3  A: 
unsigned short bar = (unsigned short) 23;

or in new speak....

unsigned short bar = static_cast<unsigned short>(23);
Tony Lambert
In C this would be the right thing to do, but IIRC C-style casts are frowned upon in C++.
starblue
frowned upon! maybe I've amended it with a up-to-date version to keep you happy!
Tony Lambert
+1  A: 

There are no modifiers for unsigned short. Integers, which has int type by default, usually implicitly converted to target type with no problems. But if you really want to explicitly indicate type, you could write the following:

unsigned short bar = static_cast<unsigned short>(23);

As I can see the only reason is to use such indication for proper deducing template type:

func( static_cast<unsigned short>(23) );

But for such case more clear would be call like the following:

func<unsigned short>( 23 );
Kirill V. Lyadvinsky
A: 

You probably shouldn't use short, unless you have a whole lot of them. It's intended to use less storage than an int, but that int will have the "natural size" for the architecture. Logically it follows that a short probably doesn't. Similar to bitfields, this means that shorts can be considered a space/time tradeoff. That's usually only worth it if it buys you a whole lot of space. You're unlikely to have very many literals in your application, though, so there was no need foreseen to have short literals. The usecases simply didn't overlap.

MSalters