来自C++标准:
标准布局类是这样一个类: -没有非标准布局类(或此类类型的数组)或引用的非静态数据成员, -没有虚拟功能(10.3),也没有虚拟基类(10.1), -对所有非静态数据成员具有相同的访问控制(第11条),-没有非标准布局基类, -在大多数派生类中没有非静态数据成员,最多有一个具有非静态数据成员的基类,或者没有具有非静态数据成员的基类,并且 -没有与第一个非静态数据成员相同类型的基类。 宏偏移量(类型,成员-指示符)在本国际标准中接受一组受限的类型参数.如果type不是标准布局类(第9条),则结果是未定义的。
考虑到这些语句,对于依赖于模板参数的成员,是否有任何安全的方法来使用offsetof?如果没有,如何获得模板类中成员的偏移量?在使用以下内容时什么可能不安全:
//MS Visual Studio 2013 definition
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))关于非标准的布局类?
以下是根据标准不安全的样本:
#include <cstddef>
#include <iostream>
template<typename T>
struct Test
{
int a;
T b;
};
struct NonStdLayout
{
virtual void f(){};
};
int main()
{
std::cout << offsetof(Test<int>, b) << std::endl;
std::cout << offsetof(Test<NonStdLayout>, b) << std::endl;
return 0;
}发布于 2014-02-05 13:00:25
offsetof不能仅仅因为内存中的布局未知而在非标准布局类上使用.例如,标准没有指定如何实现虚拟成员函数。这样做的一种常见方法是将指向vtable的指针添加为类的第一个数据成员,但这不是唯一的方法。
关于offsetof的定义:不能保证空指针通过reinterpret_cast (或C样式转换)转换为0,也没有为转换到整数的指针的其他值指定任何语义。
因此,如果--如果您知道您的定义在编译器用于平台的底层寻址方案中是有意义的--它可以工作。但这是一个,如果你必须意识到。
发布于 2014-02-06 13:38:58
答案是,在模板中使用偏移是完全安全的。不会因此造成任何伤害。但是,如果选择这样做,则对模板的参数类型施加限制。它将正确地工作在标准布局类中,原则上编译器至少应该告诉您参数何时是它不工作的类型。
无论是否涉及任何模板,都无法在标准下为非标准布局类的成员获取偏移量。它可能在单个编译器中起作用,但可能不起作用。它很可能适用于所有非虚拟类(尽管这不是标准的要求)。也许你只需要做实验。
我们经常被迫编写不符合标准的代码来解决这样的问题,因此我们在单个编译器上仔细测试它。这只是意味着在研究和测试方面有更多的努力。
https://stackoverflow.com/questions/21577845
复制相似问题