位域成员的类型
Type of bit-field members
理论上,我们有两种选择位域成员的类型:
- 基础类型的类型。
- 适合位数的最小类型。
那么位域成员的实际类型是什么(到目前为止我在标准中找不到提示——C 和 C++ 都一样),C 和 C++ 之间有什么区别吗?
虽然知道特定的编译器不是参考,但我尝试通过 C++ 函数重载和 typeid 运算符至少获得一些提示:
#include <typeinfo>
struct S
{
unsigned int n4 : 4;
unsigned int n12 : 12;
};
void f(unsigned char)
{
std::cout << "uc" << std::endl;
}
void f(unsigned short)
{
std::cout << "us" << std::endl;
}
void f(unsigned int)
{
std::cout << "ui" << std::endl;
}
int main(int argc, char* argv[])
{
S s; s.n4 = 0; s.n12 = 0;
f(s.n4);
f(s.n12);
std::cout << typeid(s.n4).name() << std::endl;
std::cout << typeid(s.n12).name() << std::endl;
std::cout << typeid(unsigned char).name() << std::endl;
std::cout << typeid(unsigned short).name() << std::endl;
std::cout << typeid(unsigned int).name() << std::endl;
return 0;
}
输出(linux 下的 GCC 5.4.0)完全令人惊讶,而且——至少在我看来——自相矛盾:
ui
ui
h
t
h
t
j
那么如果type根据typeid运算符分别是unsigned char和unsigned short,为什么在重载解析时选择了unsigned int?甚至可能是 GCC 错误?
附录:GCC 8.1 (linux) 仍然表现出相同的行为。
来自C++ standard § 10.3.10.1 (class.bit):
The bit-field attribute is not part of the type of the class member.
(我一定是在发题的时候忽略了标准中的这个短语...)
所以标准明确了位域成员的类型,它等于底层类型。
感谢Davis Herring给我适当的提示。
理论上,我们有两种选择位域成员的类型:
- 基础类型的类型。
- 适合位数的最小类型。
那么位域成员的实际类型是什么(到目前为止我在标准中找不到提示——C 和 C++ 都一样),C 和 C++ 之间有什么区别吗?
虽然知道特定的编译器不是参考,但我尝试通过 C++ 函数重载和 typeid 运算符至少获得一些提示:
#include <typeinfo>
struct S
{
unsigned int n4 : 4;
unsigned int n12 : 12;
};
void f(unsigned char)
{
std::cout << "uc" << std::endl;
}
void f(unsigned short)
{
std::cout << "us" << std::endl;
}
void f(unsigned int)
{
std::cout << "ui" << std::endl;
}
int main(int argc, char* argv[])
{
S s; s.n4 = 0; s.n12 = 0;
f(s.n4);
f(s.n12);
std::cout << typeid(s.n4).name() << std::endl;
std::cout << typeid(s.n12).name() << std::endl;
std::cout << typeid(unsigned char).name() << std::endl;
std::cout << typeid(unsigned short).name() << std::endl;
std::cout << typeid(unsigned int).name() << std::endl;
return 0;
}
输出(linux 下的 GCC 5.4.0)完全令人惊讶,而且——至少在我看来——自相矛盾:
ui
ui
h
t
h
t
j
那么如果type根据typeid运算符分别是unsigned char和unsigned short,为什么在重载解析时选择了unsigned int?甚至可能是 GCC 错误?
附录:GCC 8.1 (linux) 仍然表现出相同的行为。
来自C++ standard § 10.3.10.1 (class.bit):
The bit-field attribute is not part of the type of the class member.
(我一定是在发题的时候忽略了标准中的这个短语...)
所以标准明确了位域成员的类型,它等于底层类型。
感谢Davis Herring给我适当的提示。