你能写一个静态断言来验证数据成员的偏移量吗?

时间:2016-10-07 00:41:53

标签: c++ assert

给出以下结构:

struct ExampleStruct {
    char firstMember[8];
    uint64_t secondMember;
};

有没有办法写一个静态断言来验证secondMember的偏移量是8个字节的倍数?

2 个答案:

答案 0 :(得分:6)

Offsetof

您可以使用offsetof库带来的cstddef marco。这里我首先得到偏移量,然后使用modulus operator来检查它是否为8的倍数。然后,如果余数为0,则偏移量确实是8个字节的倍数。

// Offset.cpp
#include <iostream>
#include <string>
#include <cstddef>
#include <stdarg.h>

struct ExampleStruct {
    char firstMember[8];
    uint64_t secondMember;
};


int main()
{
     size_t offset = offsetof(ExampleStruct, secondMember);
     if(offset%8==0)
        std::cout << "Offset is a multiple of 8 bytes";
}

演示here

Offsetof static_assert

或者通过这个问题的上下文,目标是拥有static_assert。嗯,这几乎是一回事:

// OffsetAssert.cpp
#include <iostream>
#include <string>
#include <cstddef>
#include <stdarg.h>

struct ExampleStruct {
    char firstMember[8];
    uint64_t secondMember;
};


int main()
{
     size_t offset = offsetof(ExampleStruct, secondMember); // Get Offset
     static_assert(offsetof(ExampleStruct, secondMember)%8==0,"Not Aligned 8 Bytes"); // Check if the offset modulus 8 is remainer 0 , if so it is a multiple of 8
     std::cout << "Aligned 8 Bytes" << std::endl; // If Assert Passes it is aligned 8 bytes
}

演示here

输入类型

我使用std::size_t类型,因为这是您通常用于存储变量,对象等大小的类型。还因为它根据cppreference.com扩展到std::size_t表达式:

  

offsetof扩展为类型std::size_t的整数常量表达式,其值是从指定类型的对象的开头到其指定成员的偏移量(以字节为单位),包括填充如果有的话。

参考

cpprefrence

cplusplus

答案 1 :(得分:5)

如果您的类型具有标准布局,则可以使用offsetof宏:

#include <cstddef>

static_assert(offsetof(ExampleStruct, secondMember) % 8 == 0, "Bad alignment");

这个offsetof宏会产生一个常量表达式,如果不满足条件,你可以使用静态断言来产生转换错误。