Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

assert

Given the following struct:

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

Is there a way to write a static assert to verify that the offset of secondMember is some multiple of 8 bytes?

like image 894
Chuu Avatar asked Oct 07 '16 00:10

Chuu


2 Answers

Offsetof

You can use the offsetof marco brought by the cstddef library. Here I first get the offset, then I use the modulus operator to check if it is a multiple of 8. Then, if the remainder is 0, the offset is indeed a multiple of 8 bytes.

// 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";
}

Demo here

Offsetof with static_assert

Or by the context of this question, the goal is to have a static_assert. Well, that is pretty much the same thing:

// 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
}

Demo here

Type Uses

I use std::size_t type because that's the type you normally use to store sizes of variables, objects, and so on. And also because it expands to the std::size_t expression according to cppreference.com:

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.

References

cpprefrence

cplusplus

like image 193
amanuel2 Avatar answered Oct 20 '22 08:10

amanuel2


If your type has standard layout, you can use the offsetof macro:

#include <cstddef>

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

This the offsetof macro results in a constant expression, you can use a static assertion to produce a translation error if the condition is not met.

like image 45
Kerrek SB Avatar answered Oct 20 '22 09:10

Kerrek SB