🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #936

malloc czy (type *)malloc?

#936
From: Marek Kotowski
Date: Mon, 26 Jan 1998 15:43
140 lines
6064 bytes
Karpierz wrote:
>> Niech Pan  sie nie  dziwi. Nie wszyscy sa tacy lotni jak
>> Pan. :-)

> Widze ze zaczynasz (Pan) coraz bardziej "merytoryczna" dyskusje...
> To miala byc zlosliwosc lepiej wiedzacego ??? smutne...

  To nie miala byc zlosliwosc. Jesli Pan to tak odebral,
bardzo przepraszam. Uwagi takie, przynajmniej w dyskusji
z Panem, juz sie nie powtorza.

>> BTW -  nie musi Pan stosowac rzutu przy wywolaniu malloc.
>> Jest to zbedne, a nawet niewskazane.

> Oooo :) czepiamy sie !

  Tez nie. Po prostu, rzutowanie takie jest bardzo czesto
traktowane przez programistow jako obligatoryjne i uznalem,
ze mozna podkreslic, ze jest ono zbedne i niewskazane.
Wiecej: uznalem, ze rzecz jest na tyle typowa, ze nalezy
ja ujac w oddzielnym postingu.

> Tak :) ? A to mnie ubawiles (Pan) :).
> Wszedzie w ksiazce K&C jest stosowane takie rzutowanie i tez 
> bylem przekonany ze wlasnie tak jest bardziej prawidlowo, a tu
> masz.. taka wolta.. nawet niewskazane...
> Prosze o uzasadnienie.

  Pomine niemerytoryczna uwage o ubawieniu. Oto uzasadnienie:

1. Co do K&R (rozumiem, ze K&C to po prostu literowka):
   Ja nie mam przed soba teraz ksiazki K&R, ale tam,
   o ile dobrze pamietam, funkcja malloc byla typu
   char * (podobnie bylo w innych starszych kompilatorach).
   Tak czy inaczej, w wersji K&R nie bylo typu void *.
   Dlatego uzywano rzutu.

2. Funkcja malloc jest typu void *. Na mocy definicji
   wskaznik taki spelnia najsilniejsze warunki ulozenia
   obiektow w pamieci i moze byc przypisany kazdemu innemu.
   Zatem rzut przy malloc jest zbedny. W istocie konstrukcja

   SomethingPtr = malloc(sizeof(SOMETHING));

   lub klasyczniej:

   if ((SomethingPtr=malloc(sizeof(SOMETHING))) == NULL)
     ...

   jest idiomem jezyka C. Rzut przy malloc, jak wiekszosc
   rzeczy zbednych, zaciemnia kod. Tak samo jak zaciemniaja
   kod np. zbedne nawiasy w wyrazeniach, ktore sie czesto
   wstawia, bo sie nie zna dostatecznie priorytetow operatorow.

3. Jest jeszcze jedna, byc moze istotniejsza przyczyna,
   dla ktorej nie nalezy rzutowac wartosci zwracanej przez
   malloc. Otoz kasuje to - czy tez moze kasowac - ostrzezenie
   kompilatora o braku pliku definicyjnego z prototypem malloc,
   jesli pliku takiego do modulu nie wlaczono. W takiej sytuacji
   kompilator sam zbuduje sobie prototyp funkcji malloc na podstawie
   jej wywolania i nada jej domyslny typ int. Jesli w przypisaniu
   wartosci zwracanej przez malloc zmiennej wskaznikowej
   nie bedzie rzutu, kompilator rzecz oprotestuje, piszac np.
   "nonportable pointer conversion" (wartosc calkowita jest
   przypisywana wskaznikowi). Jesli rzut przy malloc bedzie,
   kompilator uzna, ze programista wie, co robi (zaznacza to
   przeciez za pomoca rzutu) i nie wypisze takiego komunikatu.
   W rezultacie na skutek rzutu moze zostac przeoczony blad
   niewlaczenia do modulu odpowiedniego pliku definicyjnego.

4. Uprzedze od razu argument, ze rzut przy malloc wyjasnia
   intencje programisty. Tak sie czasami sadzi, mowiac np, ze.

   p = (char *)malloc(100);

   wyjasnia, na co alokowana jest pamiec. Jest to chybiony argument,
   bo rzecz tu jest w samej nazwie zmiennej wskaznikowej, ktora
   powinna wyjasniac nature wskazywanego obiektu. Byloby lepiej,
   gdyby miala ona odpowiednia nazwe, np.

   SOME_STRUC *SomeStrucPtr;
   ...
   if ((SomeStrucPtr=malloc(sizeof(SOME_STRUC))) != NULL)
     ...
   Nie ma rzutu przy malloc, ale intencje sa jasne i wiadomo,
   o co chodzi.

5. Brak rzutu przy malloc jest zgodny ze standardem,
   wiecej: z jego duchem. Po to wprowadzono miedzy innymi
   jasne zasady rzutowania wskaznikow w standardzie,
   by nie trzeba bylo w takich sytuacjach stosowac rzutow.

> Osobiscie wszystkim zalecam wlasnie stosowanie rzutowania.

  Coz, kazdy zaleca to, co uwaza za wskazane. Moim
zdaniem rada Panska jest zla. Rzecza czytelnikow
jest osadzic, ktore zalecenie jest bardziej racjonalne.

> Dlaczego ?

> Podam tylko jeden prosty przyklad, na tyle malo teoretyczny 
> co bardzo zyciowy:

> char * x = malloc (123);

> Pod C sie kompiluje ? rzeczywiscie... No to piszemy "krocej"...
> Po co sie meczyc... Po kilku latach stwierdzamy ze mamy

  Nie chodzi o meczenie. Chodzi o zasade stylistyczna.

> juz kilka MB kodu w C...
> No tak, ale te obiekty i to C++. Wypada sprobowac.

> cannot convert void * to char * !

> lub tym podobnych.

To prawda. Kompilator C++ tak zareaguje w tym przypadku.
Ale C++ jest innym jezykiem niz C. To, co Pan - byc moze nie
do konca swiadomie - sugeruje, to wziac modul napisany w C, nadac
mu rozszerzenie CPP i kompilowac jako C++. To tez, moim zdaniem,
zla rada. C i C++ to sa inne filozofie programowania.
Jezyk C jest do programowania strukturalnego, C++ - do
obiektowego. Jesli Pan ma duzo kodu w jezyku C, to, owszem,
mozna go wykorzystac w projekcie programistycznym w C++,
ale jako moduly w C wlasnie, a nie jako kod w C, ktory ma
stac sie kodem w C++ (program strukturalny nie stanie sie przez
to obiektowym). Nie nalezy tez kodujac w C, myslec,
czy kupi to kompilator C++, bo wtedy grozi programiscie
swoista schizofrenia: czy ten kod w C akceptuje kompilator C++,
czy nie? A jezeli kod napisany w C jest zgodny z wymogami C++,
to czy jest to C, czy moze juz C++? A moze to juz jest nawet
programowanie obiektowe? :-)

  I tyle. Takie sa Panskie rady (moim zdaniem zle) i argumenty,
a takie sa moje. Reszte zostawmy Czytelnikom.

  Pozdrawiam

  Marek Kotowski
Technical Details
Message-ID: <34CCAF18.4877@imm.org.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!news.nask.pl!not-for-mail

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!news.icm.edu.pl!news.nask.pl!not-for-mail
From: Marek Kotowski <mkot@imm.org.pl>
Newsgroups: pl.comp.lang.c
Subject: malloc czy (type *)malloc?
Date: Mon, 26 Jan 1998 16:43:21 +0100
Organization: Instytut Maszyn Matematycznych
Lines: 140
Message-ID: <34CCAF18.4877@imm.org.pl>
NNTP-Posting-Host: 148.81.238.53
Mime-Version: 1.0
X-Mailer: Mozilla 3.01Gold (Win95; I)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit