是sizeof(枚举)== sizeof(int),总是吗? [英] Is the sizeof(enum) == sizeof(int), always?

查看:210
本文介绍了是sizeof(枚举)== sizeof(int),总是吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否是sizeof(枚举)== sizeof(int),总是?




  • 还是依赖编译器?
  • 说错了,因为编译器针对字长(内存对齐)进行了优化,也就是说,y int是特定编译器上的字大小?这是否意味着如果我使用枚举,那么没有处理惩罚,因为它们将是一致的?

  • 如果我把所有的返回码放在一个枚举中,是不是更好,我清楚不要担心它获得的值,只有在检查返回类型时的名称。如果是这样的话,#DEFINE会更好,因为它会节省内存。



通常的做法是什么?
如果我必须通过网络传输这些返回类型,并且一些处理必须在另一端完成,那么你最好使用什么枚举/#定义/ const ints。


$ b $编辑 - 只需检查网络,因为编译器不象征性地链接宏,人们如何调试然后比较整数值与头文件?



从答案 - 我在下面添加这一行,因为我需要澄清 -


所以它是实现定义的,
sizeof(enum)可能等于
sizeof(char),即1。





  • 这并不意味着编译器会检查枚举中的值范围,然后分配内存。我不这么认为,当然我不知道。有人可以解释一下可能是什么。


解决方案

枚举之间可能不同。以下是语义

 枚举X {A,B}; 

// A有类型int
assert(sizeof(A)== sizeof(int));

//某种整数类型。也许甚至int这是
//定义的实现。
assert(sizeof(enum X)== sizeof(some_integer_type));请注意,C99中的某些整数类型可能还包括扩展整数类型(但实现方式不同) ,必须记录,如果它提供它们)。枚举的类型是可以存储任何枚举器( A B 在这种情况下的值的类型) 。



我不认为使用枚举有任何处罚。枚举器也是积分常数表达式(例如,您可以使用它来初始化静态或文件范围变量),并且我希望尽可能更好地使用宏。



枚举器不需要任何运行时内存。只有在创建枚举类型的变量时,才可以使用运行时内存。只需将枚举器视为编译时常数即可。



我只会使用一种可以存储枚举值的类型(我应该知道手头的粗略范围),并将其发送到网络。优选地,该类型应该是一些固定宽度的类型,例如 int32_t ,所以当涉及不同的机器时不会出现冲突。或者我会打印数字,并在另一边扫描,这摆脱了一些这些问题。






对编辑的响应



那么编译器不需要使用任何大小。一个容易的事情是,价值观的重要性 - 无符号类型在一些计算中可以显着提高性能。以下是我的框上的GCC 4.4.0 的行为

  int main(void){
枚举X {A = 0};
枚举X a; // X与unsigned int兼容
unsigned int * p =& a;
}

但是,如果您分配一个 -1 ,则GCC选择使用 int 作为 X

$兼容的类型b
$ b

  int main(void){
枚举X {A = -1};
枚举X a; // X兼容int
int * p =& a;
}

使用选项 - short-enums ,这使得它使用仍然适合所有值的最小类型。

  int main(){
枚举X {A = 0};
枚举X a; // X与unsigned char兼容
unsigned char * p =& a;
}


Is the sizeof(enum) == sizeof(int), always ?

  • Or is it compiler dependent?
  • Is it wrong to say, as compiler are optimized for word lengths (memory alignment) ie y int is the word-size on a particular compiler? Does it means that there is no processing penalty if I use enums, as they would be word aligned?
  • Is it not better if I put all the return codes in an enum, as i clearly do not worry about the values it get, only the names while checking the return types. If this is the case wont #DEFINE be better as it would save memory.

What is the usual practice? If I have to transport these return types over a network and some processing has to be done at the other end, what would you prefer enums/#defines/ const ints.

EDIT - Just checking on net, as complier don't symbolically link macros, how do people debug then, compare the integer value with the header file?

From Answers —I am adding this line below, as I need clarifications—

"So it is implementation-defined, and sizeof(enum) might be equal to sizeof(char), i.e. 1."

  • Does it not mean that compiler checks for the range of values in enums, and then assign memory. I don't think so, of course I don't know. Can someone please explain me what is "might be".

解决方案

It is compiler dependent and may differ between enums. The following are the semantics

enum X { A, B };

// A has type int
assert(sizeof(A) == sizeof(int));

// some integer type. Maybe even int. This is
// implementation defined. 
assert(sizeof(enum X) == sizeof(some_integer_type));

Note that "some integer type" in C99 may also include extended integer types (which the implementation, however, has to document, if it provides them). The type of the enumeration is some type that can store the value of any enumerator (A and B in this case).

I don't think there are any penalties in using enumerations. Enumerators are integral constant expressions too (so you may use it to initialize static or file scope variables, for example), and i prefer them to macros whenever possible.

Enumerators don't need any runtime memory. Only when you create a variable of the enumeration type, you may use runtime memory. Just think of enumerators as compile time constants.

I would just use a type that can store the enumerator values (i should know the rough range of values before-hand), cast to it, and send it over the network. Preferably the type should be some fixed-width one, like int32_t, so it doesn't come to conflicts when different machines are involved. Or i would print the number, and scan it on the other side, which gets rid of some of these problems.


Response to Edit

Well, the compiler is not required to use any size. An easy thing to see is that the sign of the values matter - unsigned types can have significant performance boost in some calculations. The following is the behavior of GCC 4.4.0 on my box

int main(void) {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned int"
  unsigned int *p = &a;
}

But if you assign a -1, then GCC choses to use int as the type that X is compatible with

int main(void) {
  enum X { A = -1 };
  enum X a; // X compatible with "int"
  int *p = &a;
}

Using the option --short-enums of GCC, that makes it use the smallest type still fitting all the values.

int main() {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned char"
  unsigned char *p = &a;
}

这篇关于是sizeof(枚举)== sizeof(int),总是吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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