I dette spørgsmål var der nogen der i en kommentar foreslog, at jeg ikke skulle kaste resultatet af malloc
, dvs.
int *sieve = malloc(sizeof(int) * length);
i stedet for:
int *sieve = (int *) malloc(sizeof(int) * length);
Hvorfor skulle dette være tilfældet?
Nej; du kaster ikke resultatet, da:
void *
automatisk og sikkert promoveres til enhver anden pointertype i dette tilfælde.<stdlib.h>
. Dette kan forårsage nedbrud (eller, endnu værre, ikke forårsage et nedbrud før langt senere i en helt anden del af koden). Tænk på hvad der sker hvis pointere og integers har forskellig størrelse; så skjuler du en advarsel ved at caster og kan miste bits af din returnerede adresse. Bemærk: fra og med C99 er implicitte funktioner forsvundet fra C, og dette punkt er ikke længere relevant, da der ikke længere er nogen automatisk antagelse om, at udeklarerede funktioner returnerer int
.Som en præcisering skal du bemærke, at jeg sagde "du skal ikke caste", ikke "du behøver ikke at caste". Efter min mening er det en fejl at inkludere cast, selv hvis du har det rigtigt. Der er simpelthen ingen fordele ved at gøre det, men en masse potentielle risici, og at medtage gipsen indikerer, at du ikke kender til risiciene.
Bemærk også, som kommentatorer påpeger, at ovenstående taler om ren C, ikke C++. Jeg tror meget stærkt på C og C++ som separate sprog.
For yderligere at tilføje, at din kode unødigt gentager typeoplysningerne (int
), hvilket kan forårsage fejl. Det er bedre at de-referere den pointer, der bruges til at gemme returværdien, for at "låse" de to sammen:
int *sieve = malloc(length * sizeof *sieve);
Dette flytter også length
til forsiden for at øge synligheden, og dropper de overflødige parenteser med sizeof
; de er kun nødvendige når argumentet er et typenavn. Mange mennesker synes ikke at vide (eller ignorerer) dette, hvilket gør deres kode mere omstændelig. Husk: sizeof
er ikke en funktion! :)
Selvom det kan øge synligheden i nogle sjældne tilfælde at flytte length
foran, bør man også være opmærksom på, at det i det generelle tilfælde bør være bedre at skrive udtrykket som:
int *sieve = malloc(sizeof *sieve * length);
Da det at holde sizeof
først, i dette tilfælde, sikrer, at multiplikationen udføres med mindst size_t
matematik.
Sammenlign: Sammenlign: malloc(sizeof *sieve * length * width)
vs. malloc(length * width * sizeof *sieve)
den anden kan overløbe length * width
når width
og length
er mindre typer end size_t
.
I C er det ikke nødvendigt at kaste returværdien af malloc
. Pointeren til void, der returneres af malloc
, konverteres automatisk til den korrekte type. Men hvis du vil have din kode til at kompilere med en C++-compiler, er det nødvendigt med en cast. Et foretrukket alternativ blandt fællesskabet er at bruge følgende:
int *sieve = malloc(sizeof *sieve * length);
som desuden befrier dig for at skulle bekymre dig om at ændre højre side af udtrykket, hvis du nogensinde ændrer typen af sieve
.
Casts er dårlige, som folk har påpeget. Specielt pointer casts.