Main Content

Incorrect use of offsetof in C++

Incorrect arguments to offsetof macro causes undefined behavior

Description

This defect occurs when you pass arguments to the offsetof macro for which the behavior of the macro is not defined.

The offsetof macro:

offsetof(classType, aMember)
returns the offset in bytes of the data member aMember from the beginning of an object of type classType. For use in offsetof, classType and aMember have certain restrictions:

  • classType must be a standard layout class.

    For instance, it must not have virtual member functions. For more information on the requirements for a standard layout class, see C++ named requirements: StandardLayoutType.

  • aMember must not be static.

  • aMember must not be a member function.

The checker flags uses of the offsetof macro where the arguments violate one or more of these restrictions.

Risk

Violating the restrictions on the arguments of the offsetof macro leads to undefined behavior.

Fix

Use the offsetof macro only on nonstatic data members of a standard layout class.

The result details state which restriction on the offsetof macro is violated. Fix the violation.

Examples

expand all

#include <cstddef>

class myClass {
     int member1;
  public:
     int member2;
};

void func() {
  size_t off = offsetof(myClass, member2);
  // ...
}

In this example, the class myClass has two data members with different access control, one private and the other public. Therefore, the class does not satisfy the requirements of a standard layout class and cannot be used with the offsetof macro.

Correction — Use Uniform Access Control for All Data Members

If the use of offsetof is important for the application, make sure that the first argument is a class with a standard layout. For instance, see if you can work around the need for a public data member.

#include <cstddef>
  
class myClass {
     int member1;
     int member2;
  public:
     int getMember2(void) { return member2;}
     friend void func(void);
};
  
void func() {
  size_t off = offsetof(myClass, member2);
  // ...
}

Result Information

Group: Programming
Language: C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: OFFSETOF_MISUSE
Impact: Medium

Version History

Introduced in R2019a