当前位置: 首页 > 知识库问答 >
问题:

对模板类使用offsetof

魏鸿
2023-03-14

根据C标准:

标准布局类是这样的类:

-没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,

-没有虚拟函数(10.3),也没有虚拟基类(10.1),

-对所有非静态数据成员具有相同的权限改造(第11条),-没有非标准布局基类,

-在大多数派生类中没有非静态数据成员,并且最多有一个基类具有非静态数据元素,或者没有基类具有静态数据元素;以及

-没有与第一个非静态数据成员相同类型的基类

宏offsetof(类型,成员指示符)接受本国际标准中一组有限的类型参数。如果类型不是标准布局类(第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;
}

共有2个答案

薛元忠
2023-03-14

答案是在模板中使用offsetof是完全安全的。这不会造成任何伤害。但是,如果选择这样做,则会对模板的参数类型施加限制。它将对标准布局类正确工作,原则上至少编译器应该告诉您参数的类型是什么,它将无法工作。

在标准下没有办法获得非标准布局类成员的偏移量,不管是否涉及任何模板。它可能在单个编译器中工作,但也可能不工作。它可能适用于所有非虚拟类(尽管这不是标准的要求)。也许你只需要尝试。

我们经常被迫编写不符合标准的代码来解决此类问题,所以我们在各个编译器上仔细测试它。这只是意味着在研究和测试方面要更加努力。

徐隐水
2023-03-14

< code>offsetof不能用于非标准布局类,因为它们在内存中的布局是未知的。例如,标准没有规定虚拟成员函数是如何实现的。一种常见的方法是添加一个指向vtable的指针作为类的第一个数据成员,但这不是唯一的方法。

至于您对< code>offsetof的定义:不能保证空指针通过< code>reinterpret_cast(或通过C风格的转换)转换为< code>0,也没有为转换为整数的指针的其他值指定任何语义。

因此,如果您知道您的定义在编译器为您的平台使用的底层寻址方案中是有意义的,它就可以工作。但这是您必须意识到的。

 类似资料:
  • 我试图在类型s. t上专门化一个类。它忽略了给定类型的恒定性。在这种情况下,该类型是一个模板模板参数: 上面的代码在GCC 4.8.4和clang 5.0(with-std=c 11)中都抱怨bar在与匹配FOFType模板参数化的类一起使用时未定义。即使我删除了sfinae参数,仍然无法找到特化。 这个问题的一个例子可以在这里找到:https://godbolt.org/g/Cjci9C.在上面

  • 考虑下面粘贴的代码。我定义了一个非常简单的类,编译器为其生成一个隐式推导指南,这样就可以在没有显式模板参数的情况下构造它。但是,模板参数推导不适用于从仅直接转发到目标类的简单别名模板构造对象: 正如您从上面的代码注释中看到的,g给了我一个关于使用别名模板而没有模板参数的错误。我希望在这样的例子中,模板参数推导会被转发。 所以,我的问题是:这是通过明示设计目前的措辞来对班级模板的论点进行演绎的建议吗

  • 模板提供了一种简便的方式,将展现逻辑从控制器和业务逻辑中分离出来。 一般来说,模板包含应用程序的 HTML 代码,但也可以使用其他的格式,例如 XML 。 模板通常也被称为「视图」, 而它是 模型-视图-控制器 (MVC) 软件架构模式第二个元素的 一部份 。

  • Web框架把我们从WSGI中拯救出来了。现在,我们只需要不断地编写函数,带上URL,就可以继续Web App的开发了。 但是,Web App不仅仅是处理逻辑,展示给用户的页面也非常重要。在函数中返回一个包含HTML的字符串,简单的页面还可以,但是,想想新浪首页的6000多行的HTML,你确信能在Python的字符串中正确地写出来么?反正我是做不到。 俗话说得好,不懂前端的Python工程师不是好的

  • Web框架把我们从WSGI中拯救出来了。现在,我们只需要不断地编写函数,带上URL,就可以继续Web App的开发了。 但是,Web App不仅仅是处理逻辑,展示给用户的页面也非常重要。在函数中返回一个包含HTML的字符串,简单的页面还可以,但是,想想新浪首页的6000多行的HTML,你确信能在Python的字符串中正确地写出来么?反正我是做不到。 俗话说得好,不懂前端的Python工程师不是好的

  • A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template in