Пустая структура в C

У меня есть структура без членов (на данный момент), и я хотел бы знать, можно ли подавить предупреждение, которое я получаю:

warning: struct has no members

Можно ли добавить элемент и сохранить sizeof struct zero? Любое другое решение?

Ответы

Ответ 1

В c поведение пустой структуры зависит от компилятора в сравнении с С++, где оно является частью спецификации (здесь)

С++
Класс с пустой последовательностью элементов и объектов базового класса - пустой класс. Завершенные объекты и подобъекты-члены пустого типа класса должны иметь ненулевой размер.

в C он более мутный, поскольку стандарт c99 имеет некоторый язык, который подразумевает, что действительно пустые структуры не разрешены (см. ответ TrayMan), но многие компиляторы позволяют это (например, gcc).

Поскольку это зависит от компилятора, маловероятно, что в этом случае вы получите действительно портативный код. Как таковые не переносные способы подавления предупреждения могут быть вашим лучшим выбором.

Ответ 2

если вам нужен только символ struct для аргументов casting и function, просто:

typedef struct _Interface Interface;

это создаст символ непрозрачного типа.

Ответ 3

Технически это даже не верно C.

TrayMan был немного в своем анализе, да 6.2.6.1 говорит:

За исключением бит-полей объекты состоят из смежных последовательностей одного или нескольких байтов, число, порядок и кодирование которых либо явно заданы, либо определены реализацией.

но свяжите это с 6.2.5-20, в котором говорится:

- Тип структуры описывает последовательный выделенный непустой набор объектов-членов (и, в определенных случаях, неполный массив), каждый из которых имеет необязательно указанное имя и, возможно, отдельный тип. p >

и теперь вы можете заключить, что структуры будут иметь один или несколько байтов , потому что они не могут быть пустыми. Ваш код дает вам предупреждение, в то время как тот же код на самом деле не скомпилируется в Microsoft Visual Studio с ошибкой:

ошибка C2016: C требует, чтобы структура или объединение имели хотя бы один элемент

Таким образом, короткий ответ - нет, не существует переносного способа избежать этого предупреждения, потому что он говорит вам, что вы нарушаете стандарты C. Вам нужно будет использовать расширение для компилятора для его подавления.

Ответ 4

стандарт C99 несколько неоднозначен, но, похоже, пустая структура должна иметь ненулевой размер.

6.2.6.1 За исключением бит-полей объекты состоят из смежных последовательностей одного или нескольких байтов, номер, порядок и кодировка которых либо явно указаны, либо от реализации.

Ответ 5

Можно ли добавить элемент и сохранить размер структуры ноль?

Неа. FWIW, С++ допускает пустые структуры, но sizeof() всегда отличен от нуля для пустой структуры.

Любое другое решение?

Нелегкие. Стоит отметить, что пустые структуры лишь немного поддерживаются в C и не разрешены на C99.

Пустые структуры поддерживаются в С++, но разные компиляторы реализуют их с различными результатами (для смещений sizeof и struct), особенно после того, как вы начинаете бросать наследование в микс.

Ответ 6

Если вам не требуется "слишком строгая" приверженность, вы можете уйти от этого:

struct empty {
  char nothing[0];
};

Это расширение GCC.

Я как бы надеялся, что смогу использовать функцию C99 под названием "гибкие массивы", объявленную следующим образом:

struct empty99
{
  char nothing[]; // This is a C99 "flexible array".
};

но это не работает; они требуют, чтобы сначала был хотя бы один нормальный элемент структуры, они не могут быть единственным членом.

Ответ 7

struct zero_information { int:0; };

Вышеприведенный фрагмент кода даст значение не -zero из sizeof(struct zero_information), но это может помочь вам получить то, что вы ищете, как 100% всего выделенного для него хранилища, padding (доступно только через хаки, хотя я не помню с верхней части головы, если присоединение к дополнению - поведение undefined).