Подтвердить что ты не робот

Литьевые указатели

В более раннем C-коде я видел много следующего:

type_t *x = (type_t *) malloc(...);

Какая точка бросания указателя возвращается из malloc(), так как она void *? Это связано с тем, что более старые компиляторы C не поддерживали указатели void и malloc() вместо этого возвращали char *?

4b9b3361

Ответ 1

Ваше собственное объяснение является правильным. Pre-ANSI C ('K & R' C) не имел типа void * с неявным преобразованием. char * удвоен как тип псевдо void *, но вам понадобилось явное преобразование типа.

В современном C литье нахмуривается, поскольку оно может подавлять предупреждения компилятора для отсутствующего прототипа malloc. В С++ требуется кастинг (но там вы должны использовать new вместо malloc большую часть времени).

Update

Мои комментарии ниже, которые пытаются объяснить, почему требуется бросок, были немного неясны, я попытаюсь объяснить это лучше здесь. Вы можете подумать, что даже когда malloc возвращает char *, приведение не требуется, поскольку оно похоже на:

int  *a;
char *b = a;

Но в этом примере также нужен актерский состав. Вторая строка является нарушением ограничения для простого оператора присваивания (C99 6.5.1.6.1). Оба операнда указателя должны быть совместимого типа. Когда вы измените это на:

int  *a;
char *b = (char *) a;

нарушение ограничения исчезает (оба операнда теперь имеют тип char *), и результат корректно определен (для преобразования в указатель char). В "обратной ситуации":

char *c;
int  *d = (int *) c;

тот же аргумент выполняется для приведения, но когда int * имеет более строгие требования к выравниванию, чем char *, результат определяется реализацией.

Заключение: в дни до ANSI тип cast был необходим, потому что malloc вернулся char *, а не результаты кастинга - это ограничение ограничения для оператора '='.

Ответ 2

Проблема здесь не в совместимости с любым диалектом C. Задача С++. В С++ указатель void не может быть автоматически преобразован в любой другой тип указателя. Таким образом, без явного приведения этот код не будет компилироваться с помощью компилятора С++.

Ответ 3

Я не знаю, что malloc когда-либо возвращал char *.

Но неявное литье из void * в type_t * (или любой другой тип) не всегда разрешено. Следовательно, необходимость явно вводить правильный тип.

Ответ 4

Какая точка бросания указателя возвращается из malloc(), поскольку она void *?

Совсем наоборот. Перед тем, как использовать его, вам нужно указать указатель void на фактический тип, поскольку void * ничего не означает данные, хранящиеся в этом месте.