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

Can you write a static assert to verify the offset of data members?

给定以下结构:

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

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

如果您的字体采用标准布局,您可以使用 offsetof 宏:

#include <cstddef>

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

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

Offsetof

您可以使用 cstddef 库自带的 offsetof 宏。这里我先得到偏移量,然后用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

Offsetofstatic_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 表达式

The macro offsetof expands to an integral constant expression of type std::size_t, the value of which is the offset, in bytes, from the beginning of an object of specified type to its specified member, including padding if any.

参考资料

cpprefrence

cplusplus