How to specify enum size in GCC?

c, enums, gcc

Solution

You've misinterpreted the warning, what it's saying is that character literals are always of type `int`, never of type `long` or `long long`.

You can get away with something like this:

enum foo {
    garbage1 = (long long)'1' << 32 | (long long)'2' << 24 | (long long)'3' << 16 | (long long)'4' << 8 | (long long)'5',
    garbage2
};

But you still have to be careful about using little endian if you want to use the strncpy solution, make sure to use the correct shift numbers.

Problem

I want to specify an enumeration size of 64 bits for an enumeration. How is this possible through GCC? The code does not need to be 'portable' in that I am only interested in making the code work on GCC compiling for x86-32 and x86-64 Linux. That means any hack which can provide the functionality I want is fine as long as it works for those targets. Given this code: ``` #include <stdlib.h> #include <stdio.h> enum some_enum { garbage1, garbage2 }; int main(void) { enum some_enum some_val; printf("size: %lu\n", sizeof(some_val)); return EXIT_SUCCESS; } ``` This currently prints out 4, whereas I want to be able to force the size to be 8. Attempting to specify values in the enum assignment larger than 4 bytes cause a warning. For example, ``` enum some_enum { garbage1 = '12345', garbage2 }; ``` Would produce: ``` warning: character constant too long for its type [enabled by default] ``` An answer to a similar question here doesn't seem to yield any good results. That is, the same warning is produced as a result of: ``` enum some_enum { garbage1 = 'adfs', garbage2 = 'asdfasdf' }; ``` Note: the multi-character warning can be turned off by compiling with `-Wno-multichar`. Rationale Since people are interested in why I am doing this, I have written a disassembler engine. I get each part of an instruction as a string. So I want the enumeration to look like this: ``` enum mnemonic { mov = 'mov', cmp = 'cmp', sysenter = 'sysenter' }; ``` I can then store semantic information easily with some code like this: ``` enum mnemonic insn; char * example_insn = "mov"; uint64_t buf = 0; strncpy((char *)&buf, example_insn, sizeof(uint64_t)); ``` If `buf` were an `enum mnemonic` then we need to do nothing else. The `strncpy` is used to pad the bytes after the end of the string to null characters. If I am not able to do this, I would have to do something like this instead: ``` if(strcmp(example_insn, "mov") == 0) { insn = mov; } else if(strcmp(example_insn, "cmp") == 0) { insn = cmp; } ... ``` Since this routine is going to be hit millions of times, this sort of optimisation would make a huge difference. I intend to do the same for operands such as registers too.

Original source