Зачем явно приводить результат вызова malloc() к char*?
1,00
р.
р.
В некоторых отрывках кода наблюдаю приведение malloc() к (char *), (int *) и т.п. Зачем это делается? Например: char *p p = (char *) malloc(100 * sizeof(char))
Ответ Во времена динозавров в языке С не было типа void *. Идея универсального указателя void * пришла в С намного позже (причем не откуда-нибудь, а из С++). А до того времени в качестве "универсального" указательного типа использовался именно char *. Функция malloc возвращала результат именно типа char *. Именно в те времена и существовала необходимость для выполнения неявного приведения результата malloc от char * к конкретному типу указателя-получателя. В примерах кода, написанных на достандартном С, включая первые версии K&R, это приведение везде присутствует именно по этой причине. С появлением в языке типа void *, неявно приводящегося к любому указательному типу, и с последующим переходом malloc на void *, необходимость в явном приведении отпала. Однако в большом количестве старого кода его еще можно увидеть. Это приведение перекочевало и во второе издание K&R С, написанное еще до появления первого стандарта С. Несмотря на то, что второе издание задним числом привели в соответствие со стандартом С89/90, примеры кода в нем никто исправлять не стал. В результате студенты, использующие книгу K&R для обучения, "нахватываются" этот странной привычки оттуда, слепо следуя ей как "карго культу". В современном С-коде выполнять такое приведение имеет смысл разве что только в кросс-компилируемом С-С++ коде, т.к. в С++ указатель void * к другим типам сам по себе не приводится. В частности, например, при реализации кросс-компилируемых макросов и inline-функций в заголовочных файлах. (Наследием тех времен, когда в качестве универсального указателя в С использовался тип char * в современной спецификации языка является гарантия того, что объектное представление и требования выравнивания типов void * и char * обязаны совпадать.)
Справедливости ради надо заметить, что один аргумент современных любителей явно приводить результат malloc в С коде (не предназначенном для кросс-компиляции) таки содержит определенное рациональное зерно. В коде вроде T* p ... p = (T *) malloc(N * sizeof(T)) если кто-то поменяет тип указателя в объявлении p с T * на U *, но при этом забудет исправить выделение памяти через malloc, то в вызове malloc компилятором будет сгенерировано диагностическое сообщение о несоответствии типов указателей. Да, это действительно так. Однако более грамотным вариантом защиты от подобных проблем будет использование идиомы с "типонезависимым" выделением памяти p = malloc(N * sizeof *p) которое само по себе "автоматически" подстроится под вышеупомянутое изменение типа.