你能写一个静态断言来验证数据成员的偏移量吗?
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
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
表达式
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.
参考资料
给定以下结构:
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
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
表达式
The macro
offsetof
expands to an integral constant expression of typestd::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.