Разыменование типа указателя в sizeof()

У меня есть следующая структура:

typedef struct _foo_t {
    int bar;
    float buzz;
    char quux[40];
} *const foo_t;

Есть ли способ получить размер структуры, как это делается с помощью sizeof(struct _foo_t), но используя только имя foo_t? я пытался sizeof(*foo_t), но это не компилируется.

4 ответа

Я не верю, что вы можете сделать это напрямую. Вам нужно определить промежуточный typedef, если вы хотите сделать это:

typedef struct _foo_t {
    int bar;
    float buzz;
    char quux[40];
} foo_t;

typedef foo_t *const foo_tp;

// sizeof(foo_t) should work

Разыменование типа на самом деле не имеет смысла в C. Вы можете разыменовать переменную, но не тип. В C++ вы можете выполнять такие операции с типами, используя шаблоны, но это не совсем применимо, поскольку вы указываете тег C.

Вы также можете объявить фиктивную переменную соответствующего типа для вызова sizeof по выражению:

foo_tp f;
// sizeof(*f) should work

Вы можете сделать это, используя составной литерал, подобный этому:

sizeof(*(foo_t){NULL})

Вы не можете использовать имя типа в качестве операнда (не только для sizeof), поскольку выражение требует наличия типа (в C типы не являются гражданами первого класса, как в полных OO-языках, таких как Python). Однако при использовании версии в скобках вы можете использовать только имя типа - черновик C11 6.5.3.4#1/2. Понятное ограничение.

Обратите внимание, что выражение в скобках после sizeof Ключевое слово будет иметь различную грамматическую семантику: круглые скобки являются частью выражения, в то время как для имени типа они являются частью sizeof оператор (который будет работать как вызов функции). (Я действительно не хочу писать парсер для C сам.)

Я для себя обычно не typedef указатели. Это скрывает семантику и позволяет забыть об их особых (и опасных) свойствах. Исключением может быть внешний интерфейс, где указатель извне используется скорее как дескриптор, чем указатель. Но это я действительно использую только на внешней мембране.

Хорошо, как я понял из обсуждения, вы пытаетесь работать с непрозрачными указателями. Но это не сработает, если в любом случае определить тип структуры и указатель сразу. Вам нужно будет разделить это:

"hidden_stuff.h":

typedef struct HiddenStruct * const HiddenStructHandle;

"hidden_stuff.c"

#include "hidden_stuff.h"

struct HiddenStruct {
    ...
};

Наличие структуры в заголовке сломает инкапсуляцию / сокрытие.

foo_t это typedefтак что это как тип.

*foo_t не является допустимым выражением, потому что вы не можете разыменовать тип.

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

Это как написание:

typedef int * pointer_to_int_type;

size_t a = sizeof(*pointer_to_int_type);
Другие вопросы по тегам