c – 两个模板类型的sizeof,两者都来自一个基础

前端之家收集整理的这篇文章主要介绍了c – 两个模板类型的sizeof,两者都来自一个基础前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
示例代码
#include <iostream>

struct base {};

template<typename Type>
struct left : base {

   Type value;
};

template<typename Type>
struct right : base {

   Type value;
}; 

int main() {
   std::cout << "sizeof left<base> = " << sizeof(left<base>) << std::endl;
   std::cout << "sizeof left<right<base>>    = " << sizeof(left<right<base>>) << std::endl;
   std::cout << "sizeof left<right<left<right<left<base>>>>> = " << sizeof(left<right<left<right<left<base>>>>>) << std::endl;
}

产量

GCC 4.6是

sizeof left<base> = 2  
sizeof left<right<base>>    = 3  
sizeof left<right<left<right<left<base>>>>> = 6

用clang 3.1

sizeof left<base> = 2  
sizeof left<right<base>>    = 3  
sizeof left<right<left<right<left<base>>>>> = 6

随着MSVC 2012

sizeof left<base> = 1
sizeof left<right<base>>    = 1
sizeof left<right<left<right<left<base>>>>> = 1

所以,问题是,它是GCC / clang中的错误,还是实现定义,或者是正确的输出(来自标准的引用,或者这种行为的解释会很好)

解决方法

相关引用是1.8 [intro.object]第6段:

Unless an object is a bit-field or a base class subobject of zero size,the address of that object is the address of the first byte it occupies. Two objects that are not bit-fields may have the same address if one is a subobject of the other,or if at least one is a base class subobject of zero size and they are of different types; otherwise,they shall have distinct addresses.

在你的右边< T>并留下< T>对象(为什么必须使用不同的类模板?一个应该已经足够了)你们每个都有一个成员值(类型为T).每个人都需要获得自己独特的地址.从而,

sizeof(left<right<left<right<left<base>>>>>) == 1

绝对错了!有6个不同的对象:

> 5个值
>一个左<右<左<右<左< base>>>>>

并且仅左侧< right< left< right< left< base>>>>>其中一个主题(如果我记得其他规则,第一个值)可​​以共享一个地址.也就是说,对象的大小至少需要为5.由于对象在对齐时效果最好,它似乎填充到6个字节(这是奇怪的;我希望它被填充到4的倍数).

甚至大小的左< base>不能是1:已经涉及两个基础对象!一种形式为lef< base>的基类.和一个本班成员的形式.这些twobase`对象需要不同的地址,因此,大小需要至少为2.

在任何情况下,对象大小只要求它们至少有多大.他们没有任何要求他们不会比某些东西更大的要求.这被视为实施质量问题.基于此,唯一的编译器错误(假设大小引号确实是正确的)是MSVC.其他尺寸有时可能略大于预期,但这不是错误.

猜你在找的C&C++相关文章