Incorrect use of offsetof in C++

Неправильные аргументы в offsetof макрос вызывает неопределенное поведение

Описание

Этот дефект возникает, когда вы передаете аргументы в offsetof макрос, для которого не определено поведение макроса.

The offsetof макрос:

offsetof(classType, aMember)
возвращает смещение в байтах представителя данных aMember от начала объекта типа classType. Для использования в offsetof, classType и aMember иметь определенные ограничения:

  • classType должен быть стандартным классом размещения.

    Для образца он не должен иметь virtual представители. Для получения дополнительной информации о требованиях к стандартному классу размещения см. C++ именованные требования: StandardLayoutType.

  • aMember не должен быть статическим.

  • aMember не должна быть функцией представителя.

Шашечные флаги используют offsetof макрос, в котором аргументы нарушают одно или несколько из этих ограничений.

Риск

Нарушение ограничений на аргументы offsetof макрос приводит к неопределенному поведению.

Зафиксировать

Используйте offsetof макрос только для нестатических представителей данных стандартного класса размещения.

Результат подробно описывает, состояние каких ограничениях на offsetof макрос нарушен. Исправьте нарушение.

Примеры

расширить все

#include <cstddef>

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

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

В этом примере класс myClass имеют два представителей данных с разным управлением доступом, один частный, а другой открытый. Поэтому класс не удовлетворяет требованиям стандартного класса размещения и не может использоваться со offsetof макрос.

Коррекция - Используйте равномерное управление доступом для всех представителей данных

Если используется offsetof важно для приложения, убедитесь, что первый аргумент является классом со стандартным размещением. Например, посмотрите, можно ли обойти потребность в общедоступном представителе данных.

#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);
  // ...
}

Информация о результатах

Группа: Программирование
Язык: C++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : OFFSETOF_MISUSE
Влияние: Средний
Введенный в R2019a