Является ли & * p допустимым для языка C, учитывая, что p является указателем на неполный тип?

Является ли следующий пример допустимой полной единицей перевода в C?

struct foo;

struct foo *bar(struct foo *j)
{
    return &*j;
}

struct foo является неполным типом, но я не могу найти явный запрет на разыменование неполного типа в стандарте C. В частности, в §6.5.3.2 сказано:

Унарный оператор & возвращает адрес своего операнда. Если операнд имеет тип «тип», результат имеет тип «указатель на тип». Если операнд является результатом унарного оператора * , ни того, что ни оператор & не оценивается, и результат такой, как если бы оба были опущены, за исключением того, что ограничения для операторов все еще применить, и результат не является l-значением.

Тот факт, что результат не является l-значением, не имеет значения - возвращаемые значения не обязательны. Ограничения на оператор * просты:

Операнд унарного оператора * должен иметь тип указателя.

и на оператор & :

операнд унарного оператора и должен быть либо функцией указатель, результат оператора [] или унарного * , либо lvalue который обозначает объект, который не является битовым полем и не объявлен со спецификатором класса хранения регистр .

Оба эти условия тривиально удовлетворены, поэтому результат должен быть эквивалентен просто return j; .

Однако gcc 4.4 .5 не компилирует этот код. Вместо этого появляется следующая ошибка:

y.c:5: error: dereferencing pointer to incomplete type

Это дефект в gcc?

25
задан caf 4 August 2011 в 06:54
поделиться

1 ответ

Да. Указатели в C обычно имеют одинаковый размер (в некоторых встроенных системах они могут быть разными). Это означает, что компилятор может сгенерировать правильный код ассемблера для этого, даже если тип «неизвестен».

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

Причина, по которой gcc 4.4.5 жалуется, заключается в следующем: если вы используете указатели на неполный тип вне реализации, это должно работать. Но код является частью реализации, и здесь вы, вероятно, хотите иметь полный тип.

2
ответ дан 28 November 2019 в 21:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: