如何在GCC中指定枚举大小? [英] How to specify enum size in GCC?

查看:497
本文介绍了如何在GCC中指定枚举大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为枚举指定一个64位的枚举大小。如何通过海湾合作委员会?代码不需要可移植,因为我只想让代码在GCC编译x86-32和x86-64 Linux上工作。这意味着任何可以提供我想要的功能的黑客都可以,只要它适用于这些目标。

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.

给定此代码:

#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;
}

目前打印出4,而我想要强制大小为8.尝试指定大于4个字节的枚举分配中的值会导致警告。例如,

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
};

会产生:

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.

由于人们对为什么这样做感兴趣,所以我已经写了一个反汇编引擎。我将一个指令的每个部分作为一个字符串。所以我想要枚举如下所示:

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));

如果 buf 是一个枚举助记符然后我们不需要做任何事情。 strncpy 用于将字符串结束后的字节填充为空字符。如果我不能这样做,我将不得不这样做:

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.

推荐答案

你已经误解了警告,这是什么意思字符文字总是类型为 int ,从不是类型 long long long

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
};

但是,如果要使用strncpy解决方案,您仍然要小心使用小端序号,make一定要使用正确的班次号码。

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.

这篇关于如何在GCC中指定枚举大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆