1

One can assign an ASCII literal (can't call it a string) to enum value as following:

#include <iostream>
// Macro to handle BIG/LITTLE ENDIAN
// Endianness is suppoesed to handled in this macro
#define TEMP(X) X

enum t
{
    XX = 'AA', // 0x4141  or  0100 0001 0100 0001
};

int main()
{
    std::cout<<XX<<std::endl;
}

And compiler compiles it and generates a Hexa-decimal constant at compile time, 0x4141 in this case. It does generate a compilation warning as:

main.cpp:9:14: warning: multi-character character constant [-Wmultichar]
     XX = 'AA', // 0x4141  or  0100 0001 0100 0001

My question here is, can we avoid this warning?

Or can we write a more elegant code to achieve similar result, probably using templates and constexpr?

I am looking for a portable alternative, so that I can get rid of this as part of refactoring without affecting the core logic.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
g-217
  • 2,069
  • 18
  • 33
  • The "elegant" code doesn't use multibyte character constants. They are simply not portable. http://stackoverflow.com/questions/7755202/multi-character-constant-warnings – Cody Gray - on strike Aug 25 '16 at 11:52
  • 1
    Multi-character constant behaviour is implementation-defined. Don't use them, and your code will be more portable *and* not generate warnings. What's wrong with `0x4141`? – DevSolar Aug 25 '16 at 11:58
  • In gcc, this warning can be disabled with [`-Wno-multichar`](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wno-multichar-608). Be aware that you're relying on implementation defined behaviour though. So, this doesn't help you, but might help other readers. – Sander De Dycker Aug 25 '16 at 11:59
  • This is clearly not C. Don't spam tags. – too honest for this site Aug 25 '16 at 12:07
  • 2
    `XX = 'AA', // 0x4141` - There is no requirement to use ASCII encoding, it can be `0x41410000` or some other combinations. This is an XY-problem. Why do you want to use character-enums in the first place? – too honest for this site Aug 25 '16 at 12:11

1 Answers1

5

I think you want something like this — which does not use multi-character literals BTW, rather user-defined literal called _i64, as defined below:

#include <iostream>

//implementation of user-defined literal _i64
namespace details
{
    constexpr int64_t i64(char const *s, int64_t v)
    {
        //in C++11, constexpr function body has to be one-line
        //though C++14 has relaxed this rule.
        return *s ? i64(s+1, v * 256 + *s) : v;
    }
}

constexpr int64_t operator "" _i64(char const *s, unsigned long)
{
    return details::i64(s, 0);
}

//your use-case.
enum colors
{
    red   = "AA"_i64,   //0x4141
    green = "BB"_i64,   //0x4242
    blue  = "CC"_i64    //0x4343
};

int main()
{
    std::cout << std::hex << red << std::endl;
    std::cout << std::hex << green << std::endl;
    std::cout << std::hex << blue << std::endl;
}

Output (demo):

 4141
 4242
 4343
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Note that the recursive ternary gymnastic is unnecessary in C++14. – Quentin Aug 25 '16 at 11:55
  • @Quentin: Yes. C++14 has some flexibility, but my solution would work for C++11 as well. – Nawaz Aug 25 '16 at 11:56
  • I find this fascinating on one hand, but IMO it obfuscates the code. Better is to avoid such constructs. It is not really clear **why** OP want multi-character `enum`s. Most likely they can just be avoided. – too honest for this site Aug 25 '16 at 12:15
  • 1
    So the suggestion here is to write twelve lines of code instead of `'AA'`? – Pete Becker Aug 25 '16 at 12:15
  • 1
    @PeteBecker: Well, 12 lines of _portable_ code. Seems reasonable. Although as Olaf points out, you can't strictly rely on ASCII. – MSalters Aug 25 '16 at 12:22
  • 1
    @MSalters - how do you know that in the intended use (which isn't described in the question) the code was not portable? Yes, all this wheel-spinning **might** be appropriate for some uses, but that doesn't mean it's automatically the right answer in every case. – Pete Becker Aug 25 '16 at 12:27
  • @PeteBecker: I think we dont have enough information to carry out this discussion any further, do we? – Nawaz Aug 25 '16 at 12:30