为什么在前向声明时必须提供枚举的大小?
Why must an enumeration's size be provided when it is forward declared?
我只是不明白为什么枚举的大小与编译器相关而 class 的大小无关。
我的代码示例:
class A;
enum E; // must be enum E : int; in order to compile
void f(const A & param);
void f(const E & param);
我这里说的是标准 C++ 编译器。
我知道 MSVC 让它编译并且工作正常。所以问题是:
为什么这还没有标准化?
这是设计目标的不同。
前向声明 class 创建了一个不完整的类型,可以在 pointers/references 中不透明地使用。这个很有用属性.
不完整的枚举类型没有多大用处。然而,能够在不声明枚举中有哪些常量的情况下声明一个枚举是有用的。通过要求必须指定大小,可以避免来自不完整枚举类型的复杂性。
所以我最好的猜测是,在设计此功能时考虑到了编译器实现者,委员会发现不完整枚举增加的复杂性得不偿失。
这已经标准化,proposal 2764: Forward declaration of enumerations (rev. 3) 如果您指定基础类型,则允许前向声明枚举,而在此之前这是不可能的。
主要原因是,当未指定基础类型时,大小是实现定义的,并且可能取决于枚举器值。来自 C++11 标准草案 7.2
[dcl.enum]:
For an enumeration whose underlying type is not fixed, the underlying
type is an integral type that can represent all the enumerator values
defined in the enumeration. If no integral type can represent all the
enumerator values, the enumeration is ill-formed. It is
implementation-defined which integral type is used as the underlying
type except that the underlying type shall not be larger than int
unless the value of an enumerator cannot fit in an int or unsigned
int. If the enumerator-list is empty, the underlying type is as if the
enumeration had a single enumerator with value 0.
当按值传递时,不知道底层类型是一个问题是有道理的,但是当它是指针或引用时为什么会成为问题?这很重要,因为显然在某些体系结构上,char* 和 int* 可以具有不同的大小,如 comp.lang.c++ discussion: GCC and forward declaration of enum:[=19 中所述=]
[...] While on most architectures it may not be an issue, on some
architectures the pointer will have a different size, in case it is a
char pointer. So finally our imaginary compiler would have no idea
what to put there to get a ColorsEnum*[...]
我们有以下 Whosebug 答案供参考,它描述了 char* can be larger than int* 的情况,它支持上面讨论中的断言。
有些 more details on the possible sizes of pointers 看起来 char *
和 void *
是这里的两个主要例外,因此其他对象指针不应该有相同的问题。所以看起来这种情况最终对枚举来说是独一无二的。
我只是不明白为什么枚举的大小与编译器相关而 class 的大小无关。
我的代码示例:
class A;
enum E; // must be enum E : int; in order to compile
void f(const A & param);
void f(const E & param);
我这里说的是标准 C++ 编译器。 我知道 MSVC 让它编译并且工作正常。所以问题是:
为什么这还没有标准化?
这是设计目标的不同。
前向声明 class 创建了一个不完整的类型,可以在 pointers/references 中不透明地使用。这个很有用属性.
不完整的枚举类型没有多大用处。然而,能够在不声明枚举中有哪些常量的情况下声明一个枚举是有用的。通过要求必须指定大小,可以避免来自不完整枚举类型的复杂性。
所以我最好的猜测是,在设计此功能时考虑到了编译器实现者,委员会发现不完整枚举增加的复杂性得不偿失。
这已经标准化,proposal 2764: Forward declaration of enumerations (rev. 3) 如果您指定基础类型,则允许前向声明枚举,而在此之前这是不可能的。
主要原因是,当未指定基础类型时,大小是实现定义的,并且可能取决于枚举器值。来自 C++11 标准草案 7.2
[dcl.enum]:
For an enumeration whose underlying type is not fixed, the underlying type is an integral type that can represent all the enumerator values defined in the enumeration. If no integral type can represent all the enumerator values, the enumeration is ill-formed. It is implementation-defined which integral type is used as the underlying type except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0.
当按值传递时,不知道底层类型是一个问题是有道理的,但是当它是指针或引用时为什么会成为问题?这很重要,因为显然在某些体系结构上,char* 和 int* 可以具有不同的大小,如 comp.lang.c++ discussion: GCC and forward declaration of enum:[=19 中所述=]
[...] While on most architectures it may not be an issue, on some architectures the pointer will have a different size, in case it is a char pointer. So finally our imaginary compiler would have no idea what to put there to get a ColorsEnum*[...]
我们有以下 Whosebug 答案供参考,它描述了 char* can be larger than int* 的情况,它支持上面讨论中的断言。
有些 more details on the possible sizes of pointers 看起来 char *
和 void *
是这里的两个主要例外,因此其他对象指针不应该有相同的问题。所以看起来这种情况最终对枚举来说是独一无二的。