Dlaczego książka „The C Programming Language” mówi, że muszę obsadzić malloc?

158

Dziś doszedłem strona 167 z The C Programming Language (wydanie drugie Brian W. Kernighan i Dennis M. Ritchie) i okazało się, że autor mówi muszę rzucać malloc. Oto część z książki:

7.8.5 Zarządzanie pamięcią masową

Funkcje malloc i calloc dynamicznie uzyskują bloki pamięci.

void *malloc(size_t n)

zwraca wskaźnik do n bajtów niezainicjowanej pamięci lub NULL, jeśli żądanie nie może zostać spełnione.

void *calloc(size_t n, size_t size)

zwraca wskaźnik do wystarczającej ilości wolnego miejsca dla tablicy n obiektów o określonym rozmiarze lub NULL, jeśli żądanie nie może zostać spełnione. Pamięć jest inicjalizowana na zero. Wskaźnik zwrócony przez malloc lub calloc ma właściwe wyrównanie dla danego obiektu, ale musi zostać rzutowany na odpowiedni typ, jak w

int *ip;
ip = (int *) calloc(n, sizeof(int));

Wiem już, że malloc(i jego rodzina) zwraca typ void * i są dobre wyjaśnienia, dlaczego nie rzutowaćmalloc .

Ale moje pytanie brzmi: dlaczego książka mówi, że powinienem ją rzucić?

Michi
źródło
125
Ponieważ książka jest stara.
Oliver Charlesworth
12
Ponieważ nawet Słońce ma swoje ciemne plamy, byłaby moja odpowiedź. Innymi słowy, książka jest zła. Możliwe, że tekst poprzedza semantykę programu void *i nie został zaktualizowany. Zobacz także tę odpowiedź .
odpocząć
8
@Michi Książka zawiera wiele błędów merytorycznych i typograficznych (Google K&R errata), jest tylko w pewnym stopniu zgodna ze standardem C90, nie odnosi się do obecnego standardu C ani żadnych zmian językowych od 1990 roku. Najgorsze jest wypełnione zła praktyka programistyczna, zły styl i kod, który opiera się na niewłaściwie określonym zachowaniu. Z tego wszystkiego musisz się oduczyć, jeśli zostaniesz profesjonalnym programistą C.
Lundin
8
... i skontrastuj to z Dlaczego kompilator narzeka, gdy nie rzutuję wyniku malloc? Więc dla C - nie rzucaj. Dla C ++ - rzutuj, ale nie używaj, mallocponieważ NIE jest to C ++ - z wyjątkiem sytuacji, gdy musisz - ale nie powinieneś - z wyjątkiem ... AGGGHHHHHH !!!!! :-)
Bob Jarvis - Przywróć Monikę
2
@Mandrill czy przeczytałeś moje pytanie? Musiałem dla ciebie edytować moje pytanie.
Michi

Odpowiedzi:

215

Z http://computer-programming-forum.com/47-c-language/a9c4a586c7dcd3fe.htm :

W C przed ANSI - jak opisano w K & R-1 - malloc () zwrócił a char * i konieczne było rzutowanie jego wartości zwracanej we wszystkich przypadkach, w których zmienna odbiorcza również nie była char *. Nowy void *typ w standardzie C sprawia, że ​​te wygięcia są niepotrzebne.

Aby uchronić kogokolwiek przed wstydem niepotrzebnego skakania w obronie K & R-2, poprosiłem Dennisa Ritchiego o opinię, którą mógłbym zacytować na temat ważności wyroku cytowanego powyżej ze strony 142. Odpowiedział:

W każdym razie, teraz, gdy ponownie przeczytałem treść na str. 142, myślę, że to źle; jest napisany w taki sposób, że nie tylko chroni przed wcześniejszymi regułami, ale także błędnie przedstawia reguły ANSI.

David Ranieri
źródło
23
Więc zwracanym typem malloc był char, a nie void . Dziękuję Ci.
Michi
10
Wspomina się o tym również w errata web.archive.org/web/20150205025553/http://cm.bell-labs.com/cm/…
nr
18
Nie możesz czytać tej książki bez tej erraty wydrukowanej na kartkach obok ciebie.
Lundin
4
@Michi - nie, zwracany typ to char*nie char. Te dwa są bardzo różne.
Pete Becker
20
@alk: dokładnie. Czytając K&R, słuchasz dwóch guru, co jest wystarczające ;-)
Steve Jessop