How to write an unsigned short int literal?

后端 未结 9 1395
慢半拍i
慢半拍i 2021-01-07 15:53

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

相关标签:
9条回答
  • 2021-01-07 16:37

    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.

    0 讨论(0)
  • 2021-01-07 16:37

    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';
    
    0 讨论(0)
  • 2021-01-07 16:39

    There are multiple answers here, none of which are terribly satisfying. So here is a compilation answer with some added info to help explain things a little more thoroughly.

    First, avoid shorts as suggested, but if you find yourself needing them such as when working with indexed mesh data and simply switching to shorts for your index size cuts your index data size in half...then read on...

    1 While it is technically true that there is no way to express an unsigned short literal in c or C++ you can easily side step this limitation by simply marking your literal as unsigned with a 'u'.

    unsigned short myushort = 16u;
    

    This works because it tells the compiler that 16 is unsigned int, then the compiler goes looking for a way to convert it to unsigned short, finds one, most compilers will then check for overflow, and do the conversion with no complaints. The "narrowing conversion" error/warning when the "u" is left out is the compiler complaining that the code is throwing away the sign. Such that if the literal is negative such as -1 then the result is undefined. Usually this means you will get a very large unsigned value that will then be truncated to fit the short.

    2 There are multiple suggestions on how to side step this limitation, most seasoned programmers will sum these up with a "don't do that".

    unsigned short myshort = (unsigned short)16;
    unsigned short myothershort = static_cast<unsigned short>(16);
    

    While both of these work they are undesirable for 2 major reasons. First they are wordy, programmers get lazy and typing all that just for a literal is easy to skip which leads to basic errors that could have been avoided with a better solution. Second they are not free, static_cast in particular generates a little assembly code to do the conversion, and while an optimizer may(or may not) figure out that it can do the conversion its better to just write good quality code from the start.

    unsigned short myshort = 16ui16;
    

    This solution is undesirable because it limits who can read your code and understand it, it also means you are starting down the slippery slope of compiler specific code which can lead to your code suddenly not working because of the whims of some compiler writer, or some company that randomly decides to "make a right hand turn", or goes away and leaves in you in the lurch.

    unsigned short bar = L'\x17';
    

    This is so unreadable that nobody has upvoted it. And unreadable should be avoided for many good reasons.

    unsigned short bar = 0xf;
    

    This to is unreadable. While being able to read understand and convert hex is something serious programmers really need to learn it is very unreadable quick what number is this: 0xbad; Now convert it to binary...now octal.

    3 Lastly if you find all the above solutions undesirable I offer up yet another solution that is available via a user defined operator.

    constexpr unsigned short operator ""_ushort(unsigned long long x) 
    { 
        return (unsigned short)x; 
    }
    

    and to use it

    unsigned short x = 16_ushort;
    

    Admittedly this too isn't perfect. First it takes an unsigned long long and whacks it all the way down to an unsigned short suppressing potential compiler warnings along the way, and it uses the c style cast. But it is constexpr which gurantees it is free in an optimized program, yet can be stepped into during debug. It is also short and sweet so programmers are more likely to use it and it is expressive so it is easy to read and understand. Unfortunately it requires a recent compiler as what can legally be done with user defined operators has changed over the various version of C++.

    So pick your trade off but be careful as you may regret them later. Happy Programming.

    0 讨论(0)
  • 2021-01-07 16:43

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

    unsigned short bar = 0x0017;

    0 讨论(0)
  • 2021-01-07 16:44
    unsigned short bar = (unsigned short) 23;
    

    or in new speak....

    unsigned short bar = static_cast<unsigned short>(23);
    
    0 讨论(0)
  • 2021-01-07 16:50

    at least in Visual Studio (at least 2013 and newer) you can write

    23ui16
    

    for get an constant of type unsigned short.

    see definitions of INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX, etc. macros in stdint.h

    I don't know at the moment whether this is part of the standard C/C++

    0 讨论(0)
提交回复
热议问题