为什么这个数组的 sizeof() 是非法的?
Why is sizeof() of this array illegal?
我有以下数组:
static std::pair<const Type, const size_t> typemap_[];
定义为
std::pair<const talos::Message::Type, const size_t> talos::Message::typemap_[8] = {
{ talos::Message::Type::Empty, typeid(int).hash_code() },
{ talos::Message::Type::Keyboard , typeid(int).hash_code() },
...
这是为什么
sizeof(typemap_);
给出编译时错误
Error C2070 'std::pair []':
illegal sizeof operand
即使这样
sizeof(typemap_[0]);
合法且数组大小固定?
类型定义为:
enum class Type {...}
如果当前翻译单元中没有static std::pair<const Type, const size_t> typemap_[];
的定义,只有这个声明,则编译器无法可能知道它的大小,因为声明中没有大小。
编译器似乎缺少 typemap_
变量的定义。由于它是静态的,您可能将其隐藏在其中一个源文件中。
如果您将现在拥有的所有内容都放入同一个源中,该解决方案就会起作用。例如:
enum class Type {None, Some} ;
static std::pair<const Type, const size_t> typemap_[] = {
{ Type::None, typeid(int).hash_code() },
{ Type::Some , typeid(int).hash_code() },
};
int main() {
std::cout << "sizeof: " << sizeof(typemap_) << " " << sizeof(typemap_[0]);
return 0;
}
运行良好并输出 sizeof: 32 16
。
单个元素的同时 sizeof
是合法的,因为即使不知道其实际大小,编译器也知道数组由什么组成。
首先创建一个可重现的示例:
static char c[];
char c[8] = "";
int main()
{
return sizeof c;
}
好吧,这甚至无法编译,因为我们无法声明 c
静态且不完整:
49668931.cpp:1:13: error: storage size of ‘c’ isn’t known
static char c[];
^
将其更改为 extern
就可以了:
extern char c[];
char c[8] = "";
int main()
{
return sizeof c;
}
但是,如果我们在完成之前需要 c
的大小,那么当然会失败:
extern char c[];
int main()
{
return sizeof c;
}
char c[8] = "";
49668931.cpp:5:19: error: invalid application of ‘sizeof’ to incomplete type ‘char []’
return sizeof c;
^
未知边界数组是incompletely-defined对象类型;它的大小和布局是未知的。 typemap_
的声明只声明了一个未知边界的数组,没有定义我们无法获取它的大小所以 sizeof(typemap_);
失败。
an array of unknown bound or of incomplete element type, is an incompletely-defined object type. 42
42) The size and layout of an instance of an incompletely-defined object type is unknown.
The declared type of an array object might be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points (“array of unknown bound of T” and “array of N T”) are different types.
我会在声明中放入静态数组的元素数。如果稍后我更改实现文件中的数字,编译器将通过某种类型不匹配诊断通知。
也可以return静态函数中的大小,但定义必须与数组初始化驻留在同一个模块中;因此该函数可能是内联的,但绝不会是 constexpr。
我有以下数组:
static std::pair<const Type, const size_t> typemap_[];
定义为
std::pair<const talos::Message::Type, const size_t> talos::Message::typemap_[8] = {
{ talos::Message::Type::Empty, typeid(int).hash_code() },
{ talos::Message::Type::Keyboard , typeid(int).hash_code() },
...
这是为什么
sizeof(typemap_);
给出编译时错误
Error C2070 'std::pair []': illegal sizeof operand
即使这样
sizeof(typemap_[0]);
合法且数组大小固定?
类型定义为:
enum class Type {...}
如果当前翻译单元中没有static std::pair<const Type, const size_t> typemap_[];
的定义,只有这个声明,则编译器无法可能知道它的大小,因为声明中没有大小。
编译器似乎缺少 typemap_
变量的定义。由于它是静态的,您可能将其隐藏在其中一个源文件中。
如果您将现在拥有的所有内容都放入同一个源中,该解决方案就会起作用。例如:
enum class Type {None, Some} ;
static std::pair<const Type, const size_t> typemap_[] = {
{ Type::None, typeid(int).hash_code() },
{ Type::Some , typeid(int).hash_code() },
};
int main() {
std::cout << "sizeof: " << sizeof(typemap_) << " " << sizeof(typemap_[0]);
return 0;
}
运行良好并输出 sizeof: 32 16
。
单个元素的同时 sizeof
是合法的,因为即使不知道其实际大小,编译器也知道数组由什么组成。
首先创建一个可重现的示例:
static char c[];
char c[8] = "";
int main()
{
return sizeof c;
}
好吧,这甚至无法编译,因为我们无法声明 c
静态且不完整:
49668931.cpp:1:13: error: storage size of ‘c’ isn’t known
static char c[];
^
将其更改为 extern
就可以了:
extern char c[];
char c[8] = "";
int main()
{
return sizeof c;
}
但是,如果我们在完成之前需要 c
的大小,那么当然会失败:
extern char c[];
int main()
{
return sizeof c;
}
char c[8] = "";
49668931.cpp:5:19: error: invalid application of ‘sizeof’ to incomplete type ‘char []’
return sizeof c;
^
未知边界数组是incompletely-defined对象类型;它的大小和布局是未知的。 typemap_
的声明只声明了一个未知边界的数组,没有定义我们无法获取它的大小所以 sizeof(typemap_);
失败。
an array of unknown bound or of incomplete element type, is an incompletely-defined object type. 42
42) The size and layout of an instance of an incompletely-defined object type is unknown.
The declared type of an array object might be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points (“array of unknown bound of T” and “array of N T”) are different types.
我会在声明中放入静态数组的元素数。如果稍后我更改实现文件中的数字,编译器将通过某种类型不匹配诊断通知。
也可以return静态函数中的大小,但定义必须与数组初始化驻留在同一个模块中;因此该函数可能是内联的,但绝不会是 constexpr。