Do I cast the result of malloc?

The name of the picture

Do I cast the result of malloc?



In this question, someone suggested in a comment that I should not cast the result of malloc, i.e.


malloc


int *sieve = malloc(sizeof(int) * length);



rather than:


int *sieve = (int *) malloc(sizeof(int) * length);



Why would this be the case?





Also, it is more maintainable to write sieve = malloc( sizeof *sieve * length );
– William Pursell
Jul 29 '09 at 17:15





stackoverflow.com/q/7545365/168175
– Flexo
Jan 15 '12 at 20:06





@KarolyHorvath this is not the only reason. The other (and most important, IMHO), is to make code more flexible (yet not less secure or robust) if the type of sieve changes from int to, say, float. malloc( sizeof *sieve * length ); will work regardless of the type, while a cast needs maintenance, adds nothing, and may create tough to track bugs.
– MestreLion
Oct 10 '12 at 4:35


sieve


malloc( sizeof *sieve * length );





@MestreLion: "and may create tough to track bugs" - all you have to do is enable compile warnings and it's never going to happen. OTOH if you don't... you really deserve it. and, again, I'm not an advocate of using it.. all I'm saying that it's really not that important... it's mostly harmless :)
– Karoly Horvath
Oct 10 '12 at 9:44






See also Specifically, what's dangerous about casting the result of malloc()?
– Jonathan Leffler
Feb 10 '15 at 22:24


malloc()




27 Answers
27



No; you don't cast the result, since:


void *


<stdlib.h>


int



As a clarification, note that I said "you don't cast", not "you don't need to cast". In my opinion, it's a failure to include the cast, even if you got it right. There are simply no benefits to doing it, but a bunch of potential risks, and including the cast indicates that you don't know about the risks.



Also note, as commentators point out, that the above talks about straight C, not C++. I very firmly believe in C and C++ as separate languages.



To add further, your code needlessly repeats the type information (int) which can cause errors. It's better to dereference the pointer being used to store the return value, to "lock" the two together:


int


int *sieve = malloc(length * sizeof *sieve);



This also moves the length to the front for increased visibility, and drops the redundant parentheses with sizeof; they are only needed when the argument is a type name. Many people seem to not know (or ignore) this, which makes their code more verbose. Remember: sizeof is not a function! :)


length


sizeof


sizeof



While moving length to the front may increase visibility in some rare cases, one should also pay attention that in the general case, it should be better to write the expression as:


length


int *sieve = malloc(sizeof *sieve * length);



Since keeping the sizeof first, in this case, ensures multiplication is done with at least size_t math.


sizeof


size_t



Compare: malloc(sizeof *sieve * length * width) vs. malloc(length * width * sizeof *sieve) the second may overflow the length * width when width and length are smaller types than size_t.


malloc(sizeof *sieve * length * width)


malloc(length * width * sizeof *sieve)


length * width


width


length


size_t





@unwind No, even in strict C code, I use the cast for portability. What I mean by portability is portable for older versions of the c standard where void*'s dont get promoted. I quote from K&R's "The C Programming Language": "In C, the proper method is to declare that malloc returns a pointer to void, then explicitly coerce the pointer into the desired type with a cast." The reason that I impose such a requirement is that you dont always have a choice of what compiler you can use.
– chacham15
Feb 29 '12 at 21:44






@chacham15 While there were earlier versions of the C language where the cast was necessary (K&R C didn't have a void* type!), those versions were never standard. C89 (the first standardized version) required that malloc return void* and that void* be implicitly convertible.
– jamesdlin
Mar 27 '16 at 4:04



void*


malloc


void*


void*





@Soumen It's perhaps too obscure; without the include a return type of int will be assumed, which might be smaller than void *, so the assignment might generate a warning, which would be suppressed by the cast. See this question for instance.
– unwind
May 4 '16 at 8:21


int


void *





@unwind Most compilers will warn you about an implicitly defined function...(so I don't see the danger of the cast)
– DarthRubik
Aug 3 '16 at 1:31





@n.m. Ok. I think it's bad to assume that anyone reading here has a particular compiler. Also, since C11 the entire "implicit function" concept is gone, I didn't know that. Still, I don't see the point in adding a pointless cast. Do you also do int x = (int) 12; just to make things clear?
– unwind
Dec 8 '16 at 12:48


int x = (int) 12;



In C, you don't need to cast the return value of malloc. The pointer to void returned by malloc is automagically converted to the correct type. However, if you want your code to compile with a C++ compiler, a cast is needed. A preferred alternative among the community is to use the following:


malloc


malloc


int *sieve = malloc(sizeof *sieve * length);



which additionally frees you from having to worry about changing the right-hand side of the expression if ever you change the type of sieve.


sieve



Casts are bad, as people have pointed out. Specially pointer casts.





@MAKZ I'd argue that malloc(length * sizeof *sieve) makes it look like sizeof is a variable - so I think malloc(length * sizeof(*sieve)) is more readable.
– Michael Anderson
Apr 30 '15 at 7:02


malloc(length * sizeof *sieve)


sizeof


malloc(length * sizeof(*sieve))





And malloc(length * (sizeof *sieve)) more readable still. IMHO.
– Toby Speight
Aug 20 '15 at 13:01


malloc(length * (sizeof *sieve))





@Michael Anderson () issue aside, note that your suggested style switched the order., Consider when element count is computed like length*width, keeping the sizeof first in this case insures multiplication is done with at least size_t math. Compare malloc(sizeof( *ptr) * length * width) vs. malloc(length * width * sizeof (*ptr)) - the 2nd may overflow the length*width when width,length are smaller types that size_t.
– chux
Dec 10 '15 at 16:40



()


length*width


sizeof


size_t


malloc(sizeof( *ptr) * length * width)


malloc(length * width * sizeof (*ptr))


length*width


width,length


size_t





@chux it's not obvious, but the answer has been edited so that my comment is less pertinent - the original suggestion was malloc(sizeof *sieve * length)
– Michael Anderson
Dec 11 '15 at 0:18


malloc(sizeof *sieve * length)





C is not C++. Pretending that they are will ultimately lead to confusion and sadness. If you're using C++, then a C-style cast is also bad (unless you're using a very old C++ compiler). And static_cast>() (or reinterpret_cast<>() )is not compatible with any dialect of C.
– David C.
Feb 12 '16 at 23:12



static_cast>()


reinterpret_cast<>()



You do cast, because:


type *


type **


#include


malloc()





@ulidtko In case you did not know, it's possible to write code which compiles both as C and as C++. In fact most header files are like this, and they often contain code (macros and inline functions). Having a .c/.cpp file to compile as both is not useful very often, but one case is adding C++ throw support when compiled with C++ compiler (but return -1; when compiled with C compiler, or whatever).
– hyde
Mar 26 '13 at 11:09



.c


.cpp


throw


return -1;





If someone had malloc calls inline in a header I wouldn't be impressed, #ifdef __cplusplus and extern "C" are for this job, not adding in extra casts.
– paulm
May 6 '13 at 17:55





Well, point 1 is irrelevant, since C != C++, the other points are also trivial, if you use the variable in your malloc call: char **foo = malloc(3*sizeof(*foo)); if quite full-proof: 3 pointers to char pointers. then loop, and do foo[i] = calloc(101, sizeof(*(foo[i])));. Allocate array of 101 chars, neatly initialized to zeroes. No cast needed. change the declaration to unsigned char or any other type, for that matter, and you're still good
– Elias Van Ootegem
Dec 23 '13 at 15:37


malloc


char **foo = malloc(3*sizeof(*foo));


foo[i] = calloc(101, sizeof(*(foo[i])));


unsigned char





When I tought I got it, there it comes! Fantastic answer. Its the first time here in StackOverflow that I +1 two opposite answers! +1 No, you dont cast, and +1 Yes, you do cast! LOL. You guys are terrific. And for me and my students, I made my mind: I do cast. The kind of errors students make are more easily spotted when casting.
– Dr Beco
Sep 26 '14 at 3:22





@Leushenko: Repeating yourself in a way that cannot be validated by machine nor by local inspection is bad. Repeating yourself in ways that can be validated by such means is less bad. Given struct Zebra *p; ... p=malloc(sizeof struct Zebra);, the malloc can't avoid duplciating information about p's type, but neither the compiler nor local code inspection would detect any problem if one type changed but the other didn't. Change the code to p=(struct Zebra*)malloc(sizeof struct Zebra); and the compiler will squawk if the cast type doesn't match p, and local inspection will reveal...
– supercat
Sep 18 '15 at 17:46



struct Zebra *p; ... p=malloc(sizeof struct Zebra);


p=(struct Zebra*)malloc(sizeof struct Zebra);


p



As other stated, it is not needed for C, but for C++. If you think you are going to compile your C code with a C++ compiler, for which reasons ever, you can use a macro instead, like:


#ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif



That way you can still write it in a very compact way:


int *sieve = NEW(int, 1);



and it will compile for C and C++.





Since you're using a macro anyway, why don't you use new in the definition of C++?
– Hosam Aly
Mar 4 '09 at 6:13


new





Because there is no reason to do so. It is mainly for C programs that are compiled with a C++ compiler. If you are going to use 'new', the only thing you get are problems. You need then also a macro for free. And you need a macro to free an array, a differentiation that doesn't exists in C.
– quinmars
Mar 4 '09 at 8:51





Not to mention if it's not you who frees the memory but maybe a C library you are using, etc. Many possible problems without any gain.
– quinmars
Mar 4 '09 at 8:53





@Hosam: Yes, it definitely is. If you use new you must use delete and if you use malloc() you must you free(). Never mix them.
– Graeme Perrow
Jul 16 '11 at 17:10


new


delete


malloc()


free()





If one is going to take this approach, calling the macro NEW is probably a bad idea since the resource is never returned using delete (or DELETE) so you're mixing your vocabulary. Instead, naming it MALLOC, or rather CALLOC in this case, would make more sense.
– mah
Apr 16 '14 at 15:23


NEW


delete


DELETE


MALLOC


CALLOC



In C you can implicitly convert a void pointer to any other kind of pointer, so a cast is not necessary. Using one may suggest to the casual observer that there is some reason why one is needed, which may be misleading.



From the Wikipedia



Advantages to casting



Including the cast may allow a C program or function to compile as C++.



The cast allows for pre-1989 versions of malloc that originally returned a char *.



Casting can help the developer identify inconsistencies in type sizing should the destination pointer type change, particularly if the pointer is declared far from the malloc() call (although modern compilers and static analyzers can warn on such behaviour without requiring the cast).



Disadvantages to casting



Under the ANSI C standard, the cast is redundant.



Adding the cast may mask failure to include the header stdlib.h, in
which the prototype for malloc is found. In the absence of a
prototype for malloc, the standard requires that the C compiler
assume malloc returns an int. If there is no cast, a warning is
issued when this integer is assigned to the pointer; however, with
the cast, this warning is not produced, hiding a bug. On certain
architectures and data models (such as LP64 on 64-bit systems, where
long and pointers are 64-bit and int is 32-bit), this error can
actually result in undefined behaviour, as the implicitly declared
malloc returns a 32-bit value whereas the actually defined function
returns a 64-bit value. Depending on calling conventions and memory
layout, this may result in stack smashing. This issue is less likely
to go unnoticed in modern compilers, as they uniformly produce
warnings that an undeclared function has been used, so a warning will
still appear. For example, GCC's default behaviour is to show a
warning that reads "incompatible implicit declaration of built-in
function" regardless of whether the cast is present or not.



If the type of the pointer is changed at its declaration, one may
also, need to change all lines where malloc is called and cast.



Although malloc without casting is preferred method and most experienced programmers choose it, you should use whichever you like having aware of the issues.



i.e: If you need to compile C program as C++(Although those are separate language) you should use malloc with casting.


malloc





What does "Casting can help the developer identify inconsistencies in type sizing should the destination pointer type change, particularly if the pointer is declared far from the malloc() call" mean? Could you give an example?
– Cool Guy
May 14 '16 at 6:26


malloc()





@CoolGuy: See an earlier comment on another answer. But note that the p = malloc(sizeof(*p) * count) idiom picks up changes in the type automatically, so you don't have to get warnings and go change anything. So this isn't a real advantage vs. the best alternative for not-casting.
– Peter Cordes
Oct 24 '16 at 15:02


p = malloc(sizeof(*p) * count)





This is the proper answer: There are pros and cons, and it boils down to a matter of taste (unless the code must compile as C++ -- then the cast is mandatory).
– Peter A. Schneider
Nov 15 '16 at 17:00





Point 3 is moot, since If the type of the pointer is changed at its declaration, one should check every instance of malloc, realloc and free inolving that type. Casting will force you to do just that.
– Michaël Roy
Jun 18 '17 at 1:46




You don't cast the result of malloc, because doing so adds pointless clutter to your code.



The most common reason why people cast the result of malloc is because they are unsure about how the C language works. That's a warning sign: if you don't know how a particular language mechanism works, then don't take a guess. Look it up or ask on Stack Overflow.



Some comments:



A void pointer can be converted to/from any other pointer type without an explicit cast (C11 6.3.2.3 and 6.5.16.1).



C++ will however not allow an implicit cast between void* and another pointer type. So in C++, the cast would have been correct. But if you program in C++, you should use new and not malloc(). And you should never compile C code using a C++ compiler.


void*


new



If you need to support both C and C++ with the same source code, use compiler switches to mark the differences. Do not attempt to sate both language standards with the same code, because they are not compatible.



If a C compiler cannot find a function because you forgot to include the header, you will get a compiler/linker error about that. So if you forgot to include <stdlib.h> that's no biggie, you won't be able to build your program.


<stdlib.h>



On ancient compilers that follow a version of the standard which is more than 25 years old, forgetting to include <stdlib.h> would result in dangerous behavior. Because in that ancient standard, functions without a visible prototype implicitly converted the return type to int. Casting the result from malloc explicitly would then hide away this bug.


<stdlib.h>


int



But that is really a non-issue. You aren't using a 25 years old computer, so why would you use a 25 years old compiler?





"pointless clutter" is dismissive hyperbole that tends to derail any possibility of convincing anyone who doesn't already agree with you. A cast certainly isn't pointless; Ron Burk's and Kaz's answers make arguments in favor of casting that I very much agree with. Whether those concerns weigh more than the concerns you mention is a reasonable question to ask. To me, your concerns look relatively minor compared to theirs.
– Don Hatch
Nov 2 '16 at 8:43





"A void pointer can be converted to/from any other pointer type without an explicit cast" is not supported by 6.3.2.3. Perhaps you are thinking of "pointer to any object type"? "void pointer" and "pointer to a function" are not so readily convertible.
– chux
Jul 27 '17 at 21:07





Indeed the reference was incomplete. The relevant part for the "implicitness" is the rule of simple assignment 6.5.16.1. "one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void". I've added this reference to the answer for completeness.
– Lundin
Apr 12 at 8:55




In C you get an implicit conversion from void* to any other (data) pointer.


void*





@Jens: OK, maybe the more proper wording is "implicit conversion". Like use of integral variable in floating point expression.
– EFraim
Apr 29 '12 at 7:17





@EFraim That would actually result in a cast, and an implicit one at that.
– Mad Physicist
Nov 3 '15 at 19:13




Casting the value returned by malloc() is not necessary now, but I'd like to add one point that seems no one has pointed out:


malloc()



In the ancient days, that is, before ANSI C provides the void * as the generic type of pointers, char * is the type for such usage. In that case, the cast can shut down the compiler warnings.


void *


char *



Reference: C FAQ





Shutting up compiler warnings is a bad idea.
– Albert van der Horst
Apr 1 '16 at 17:33





@AlbertvanderHorst Not if you're doing so by solving the exact problem the warning is there to warn you of.
– Dan Bechard
Apr 11 '16 at 17:17






@Dan . If by solving the exact problem is meant a rewrite of a subroutine to return modern ANSI C types instead of char *, I agree. I wouldn't call that shutting up the compiler. Do not give in to managers who insists that there are no compiler warnings , instead of using them by each recompilation to find possible problems. Groetjes Albert
– Albert van der Horst
Nov 2 '16 at 16:51




It is not mandatory to cast the results of malloc, since it returns void* , and a void* can be pointed to any datatype.


malloc


void*


void*



Just adding my experience, studying computer engineering I see that the two or three professors that I have seen writing in C always cast malloc, however the one I asked (with an immense CV and understanding of C) told me that it is absolutely unnecessary but only used to be absolutely specific, and to get the students into the mentality of being absolutely specific. Essentially casting will not change anything in how it works, it does exactly what it says, allocates memory, and casting does not effect it, you get the same memory, and even if you cast it to something else by mistake (and somehow evade compiler errors) C will access it the same way.



Edit: Casting has a certain point. When you use array notation, the code generated has to know how many memory places it has to advance to reach the beginning of the next element, this is achieved through casting. This way you know that for a double you go 8 bytes ahead while for an int you go 4, and so on. Thus it has no effect if you use pointer notation, in array notation it becomes necessary.





Except as already mentioned, the cast might hide bugs and make the code harder to analyse for the compiler or static analyser.
– Lundin
May 27 '14 at 7:56





"Essentially casting will not change anything in how it works". Casting to the matching type should not change anything, but should the var's type change and the cast no longer match, could problems come up? IWOs, the cast and var type should be kept in sync - twice the maintenance work.
– chux
Aug 23 '14 at 19:29





I can see why Profs prefer casting. Casting may be useful from an educational standpoint where it conveys to the instructor information and the student code does not need to be maintained - its throw-away code. Yet from a coding, peer-review and maintenance perspective, p = malloc(sizeof *p * n); is so simple and better.
– chux
Jul 27 '17 at 21:38


p = malloc(sizeof *p * n);



The returned type is void*, which can be cast to the desired type of data pointer in order to be dereferenceable.





void* can be cast to the desired type, but there is no need to do so as it will be automatically converted. So the cast is not necessary, and in fact undesirable for the reasons mentioned in the high-scoring answers.
– Toby Speight
Aug 20 '15 at 12:59


void*



A void pointer is a generic pointer and C supports implicit conversion from a void pointer type to other types, so there is no need of explicitly typecasting it.



However, if you want the same code work perfectly compatible on a C++ platform, which does not support implicit conversion, you need to do the typecasting, so it all depends on usability.





It's not a normal use case to compile a single source as both C and C++ (as opposed, say, to using a header file containing declarations to link C and C++ code together). Using malloc and friends in C++ is a good warning sign that it deserves special attention (or re-writing in C).
– Toby Speight
Aug 20 '15 at 12:57


malloc



Adding to all the information here; this is what The GNU C Library Reference manual says:



You can store the result of malloc into any pointer variable without a
cast, because ISO C automatically converts the type void * to another
type of pointer when necessary. But the cast is necessary in contexts
other than assignment operators or if you might want your code to run
in traditional C.


malloc


void *



And indeed the ISO C11 standard (p347) says so:



The pointer returned if the allocation succeeds is suitably aligned so
that it may be assigned to a pointer to any type of object with a
fundamental alignment requirement and then used to access such an
object or an array of such objects in the space allocated (until the
space is explicitly deallocated)



It depends on the programming language and compiler. If you use malloc in C there is no need to type cast it, as it will automatically type cast, However if your using C++ then you should type cast because malloc will return a void* type.


malloc


malloc


void*





The function malloc returns a void pointer in C as well but the rules of the language are different from C++.
– August Karlstrom
Sep 5 '15 at 9:19




In the C language, a void pointer can be assigned to any pointer, which is why you should not use a type cast. If you want "type safe" allocation, I can recommend the following macro functions, which I always use in my C projects:


#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)



With these in place you can simply say


NEW_ARRAY(sieve, length);



For non-dynamic arrays, the third must-have function macro is


#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])



which makes array loops safer and more convenient:


int i, a[100];

for (i = 0; i < LEN(a); i++)
...





"a void pointer can be assigned to any object pointer" Function pointers are another issue, albeit not a malloc() one.
– chux
Jul 27 '17 at 21:39



malloc()





Assigning a void* to/from a function pointer may lose information so "a void pointer can be assigned to any pointer," is a problem in those cases. Assigning a void*, from malloc() to any object pointer is not an issue though.
– chux
Dec 26 '17 at 19:09



void*


void*


malloc()





The do loop comment related to macros involving a loop yet that is wondering away from the title question. Removing that comment. Will take this one down later too.
– chux
Dec 27 '17 at 15:44



do



Casting is only for C++ not C.In case you are using a C++ compiler you better change it to C compiler.



People used to GCC and Clang are spoiled. It's not all that good out there.



I have been pretty horrified over the years by the staggeringly aged compilers I've been required to use. Often companies and managers adopt an ultra-conservative approach to changing compilers and will not even test if a new compiler ( with better standards compliance and code optimization ) will work in their system. The practical reality for working developers is that when you're coding you need to cover your bases and, unfortunately, casting mallocs is a good habit if you cannot control what compiler may be applied to your code.



I would also suggest that many organizations apply a coding standard of their own and that that should be the method people follow if it is defined. In the absence of explicit guidance I tend to go for most likely to compile everywhere, rather than slavish adherence to a standard.



The argument that it's not necessary under current standards is quite valid. But that argument omits the practicalities of the real world. We do not code in a world ruled exclusively by the standard of the day, but by the practicalities of what I like to call "local management's reality field". And that's bent and twisted more than space time ever was. :-)



YMMV.



I tend to think of casting malloc as a defensive operation. Not pretty, not perfect, but generally safe. ( Honestly, if you've not included stdlib.h then you've way more problems than casting malloc ! ).





Well stated alternative view, but what does YMMV mean? (your mileage may vary is the most common definition I could find, but do not see how it applies here :)
– ryyker
Apr 25 '17 at 15:13




I put in the cast simply to show disapproval of the ugly hole in the type system, which allows code such as the following snippet to compile without diagnostics, even though no casts are used to bring about the bad conversion:


double d;
void *p = &d;
int *q = p;



I wish that didn't exist (and it doesn't in C++) and so I cast. It represents my taste, and my programming politics. I'm not only casting a pointer, but effectively, casting a ballot, and casting out demons of stupidity. If I can't actually cast out stupidity, then at least let me express the wish to do so with a gesture of protest.



In fact, a good practice is to wrap malloc (and friends) with functions that return unsigned char *, and basically never to use void * in your code. If you need a generic pointer-to-any-object, use a char * or unsigned char *, and have casts in both directions. The one relaxation that can be indulged, perhaps, is using functions like memset and memcpy without casts.


malloc


unsigned char *


void *


char *


unsigned char *


memset


memcpy



On the topic of casting and C++ compatibility, if you write your code so that it compiles as both C and C++ (in which case you have to cast the return value of malloc when assigning it to something other than void *), you can do a very helpful thing for yourself: you can use macros for casting which translate to C++ style casts when compiling as C++, but reduce to a C cast when compiling as C:


malloc


void *


/* In a header somewhere */
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast<TYPE>(EXPR))
#define convert(TYPE, EXPR) (static_cast<TYPE>(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast<TYPE>(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif



If you adhere to these macros, then a simple grep search of your code base for these identifiers will show you where all your casts are, so you can review whether any of them are incorrect.


grep



Then, going forward, if you regularly compile the code with C++, it will enforce the use of an appropriate cast. For instance, if you use strip_qual just to remove a const or volatile, but the program changes in such a way that a type conversion is now involved, you will get a diagnostic, and you will have to use a combination of casts to get the desired conversion.


strip_qual


const


volatile



To help you adhere to these macros, the the GNU C++ (not C!) compiler has a beautiful feature: an optional diagnostic which is produced for all occurrences of C style casts.



If your C code compiles as C++, you can use this -Wold-style-cast option to find out all occurrences of the (type) casting syntax that may creep into the code, and follow up on these diagnostics by replacing it with an appropriate choice from among the above macros (or a combination, if necessary).


-Wold-style-cast


(type)



This treatment of conversions is the single largest standalone technical justification for working in a "Clean C": the combined C and C++ dialect, which in turn technically justifies casting the return value of malloc.


malloc





As other pointed out, I would usually recommend to not mix C and C++ code. However, if you have good reason to do it, then macros might be useful.
– Phil1970
Jun 10 '16 at 15:53





@Phil1970 It's all written in one cohesive dialect, which happens to be portable to C and C++ compilers, and takes advantage of some capabilities of C++. It must be all compiled as C++, or else all compiled as C.
– Kaz
Jun 10 '16 at 16:45





I.e. what I was trying to say in the previous comment is that there is no mixing of C and C++. The intent is that the code is all compiled as C or all compiled as C++.
– Kaz
Jun 14 '16 at 17:35



The concept behind void pointer is that it can be casted to any data type that is why malloc returns void. Also you must be aware of automatic typecasting. So it is not mandatory to cast the pointer though you must do it. It helps in keeping the code clean and helps debugging





"It is not mandatory -- though you must do it" - I think there's a contradiction there!
– Toby Speight
Aug 20 '15 at 12:54





I think you should read this post to someone, and see if they understand what you are trying to say. Then rewrite it, making it clear what you want to say. I really can't understand what your answer is.
– Bill Woodger
Sep 8 '15 at 12:28



The best thing to do when programming in C whenever it is possible:


-Wall


auto


-Wall


-std=c++11



This procedure lets you take advantage of C++ strict type checking, thus reducing the number of bugs. In particular, this procedure forces you to include stdlib.hor you will get


stdlib.h



malloc was not declared within this scope


malloc



and also forces you to cast the result of malloc or you will get


malloc



invalid conversion from void* to T*


void*


T*



or what ever your target type is.



The only benefits from writing in C instead of C++ I can find are



Notice that the second cons should in the ideal case disappear when using the subset common to C together with the static polymorphic feature.



For those that finds C++ strict rules inconvenient, we can use the C++11 feature with inferred type


auto memblock=static_cast<T*>(malloc(n*sizeof(T))); //Mult may overflow...





Use a C compiler for C code. Use a C++ compiler for C++ code. No ifs, no buts. Rewriting your C code in C++ is another thing entirely, and may - or may not be - worth the time and the risks.
– Toby Speight
Jun 25 '15 at 21:06





I'd like to add to @TobySpeight advice: If you need to use C code in a C++ project, you can usually compile the C code as C (e.g. gcc -c c_code.c), the C++ code as C++ (e.g. g++ -c cpp_code.cpp), and then link them together (e.g. gcc c_code.o cpp_code.o or vice-versa depending upon the project dependencies). Now there should be no reason to deprive yourself of any nice features of either language...
– autistic
Dec 7 '15 at 16:06


gcc -c c_code.c


g++ -c cpp_code.cpp


gcc c_code.o cpp_code.o





@seb but when would you need to?
– user877329
Dec 7 '15 at 18:59





@user877329 It's a more sensible alternative to painstakingly adding casts to code that reduce the code's legibility, only for the sake of being "C++ compatible".
– autistic
Dec 8 '15 at 0:54





Probably the main advantage in this context is that C lets you write p = malloc(sizeof(*p));, which doesn't need changing in the first place if p changes to a different type name. The proposed "advantage" of casting is that you get a compile error if p is the wrong type, but it's even better if it Just Works.
– Peter Cordes
Oct 24 '16 at 15:13


p = malloc(sizeof(*p));


p


p


malloc()



In general, you don't cast to or from void *.


void *



A typical reason given for not doing so is that failure to #include <stdlib.h> could go unnoticed. This isn't an issue anymore for a long time now as C99 made implicit function declarations illegal, so if your compiler conforms to at least C99, you will get a diagnostic message.


#include <stdlib.h>



But there's a much stronger reason not to introduce unnecessary pointer casts:



In C, a pointer cast is almost always an error. This is because of the following rule (§6.5 p7 in N1570, the latest draft for C11):



An object shall have its stored value accessed only by an lvalue expression that has one of
the following types:

— a type compatible with the effective type of the object,

— a qualified version of a type compatible with the effective type of the object,

— a type that is the signed or unsigned type corresponding to the effective type of the
object,

— a type that is the signed or unsigned type corresponding to a qualified version of the
effective type of the object,

— an aggregate or union type that includes one of the aforementioned types among its
members (including, recursively, a member of a subaggregate or contained union), or

— a character type.



This is also known as the strict aliasing rule. So the following code is undefined behavior:


long x = 5;
double *p = (double *)&x;
double y = *p;



And, sometimes surprisingly, the following is as well:


struct foo int x; ;
struct bar int x; int y; ;
struct bar b = 1, 2;
struct foo *p = (struct foo *)&b;
int z = p->x;



Sometimes, you do need to cast pointers, but given the strict aliasing rule, you have to be very careful with it. So, any occurrence of a pointer cast in your code is a place you have to double-check for its validity. Therefore, you never write an unnecessary pointer cast.



In a nutshell: Because in C, any occurrence of a pointer cast should raise a red flag for code requiring special attention, you should never write unnecessary pointer casts.



Side notes:



There are cases where you actually need a cast to void *, e.g. if you want to print a pointer:


void *


int x = 5;
printf("%pn", (void *)&x);



The cast is necessary here, because printf() is a variadic function, so implicit conversions don't work.


printf()



In C++, the situation is different. Casting pointer types is somewhat common (and correct) when dealing with objects of derived classes. Therefore, it makes sense that in C++, the conversion to and from void * is not implicit. C++ has a whole set of different flavors of casting.


void *





In your examples you avoid void *. there is a difference between cast from double * to int * and vice versa. malloc returns pointel aligned to the largest standard type so there are no aliasing rules broken even if someone casts form this aligned pointer to other type.
– P__J__
Aug 22 '17 at 16:38





Aliasing has nothing at all to do with alignment and for the rest of your comment -- you obviously didn't get the point.
– Felix Palmen
Aug 22 '17 at 16:43





@PeterJ: just in case, the point is to avoid an unnecessary pointer cast, so it doesn't look like a piece of code you have to pay special attention to.
– Felix Palmen
Aug 22 '17 at 16:48





The strict aliasing issue doesn't really have anything to do with void pointers. In order to get bugs caused by strict aliasing violations, you must de-reference the pointed-at data. And since you can't de-reference a void pointer, such bugs are per definition not related to the void pointer but to something else.
– Lundin
Aug 23 '17 at 6:33





Rather, you would have to make a rule to ban all pointer casts. But then how would you write things like serialization routines and hardware-related programming? Things that are C's strength. Such casts are fine if you know what you are doing.
– Lundin
Aug 23 '17 at 6:36



I prefer to do the cast, but not manually. My favorite is using g_new and g_new0 macros from glib. If glib is not used, I would add similar macros. Those macros reduce code duplication without compromising type safety. If you get the type wrong, you would get an implicit cast between non-void pointers, which would cause a warning (error in C++). If you forget to include the header that defines g_new and g_new0, you would get an error. g_new and g_new0 both take the same arguments, unlike malloc that takes fewer arguments than calloc. Just add 0 to get zero-initialized memory. The code can be compiled with a C++ compiler without changes.


g_new


g_new0


g_new


g_new0


g_new


g_new0


malloc


calloc


0



A void pointer is a generic pointer and C supports implicit conversion from a void pointer type to other types, so there is no need of explicitly typecasting it.



However, if you want the same code work perfectly compatible on a C++ platform, which does not support implicit conversion, you need to do the typecasting, so it all depends on usability.



As other stated, it is not needed for C, but for C++.



Including the cast may allow a C program or function to compile as C++.



In C it is unnecessary, as void * is automatically and safely promoted to any other pointer type.



But if you cast then, it can hide an error if you forgot to include
stdlib.h. This can cause crashes (or, worse, not cause a crash
until way later in some totally different part of the code).



Because stdlib.h contains the prototype for malloc is found. In the
absence of a prototype for malloc, the standard requires that the C
compiler assumes malloc returns an int. If there is no cast, a
warning is issued when this integer is assigned to the pointer;
however, with the cast, this warning is not produced, hiding a bug.



The casting of malloc is unnecessary in C but mandatory in C++.


<stdlib.h>



Please do yourself a favor and more importantly a favor for the next person who will maintain your code, and provide as much information as possible about the data type of a program's variables.



Thus, cast the returned pointer from malloc. In the following code the compiler can be assured that sieve is in fact being assigned a point to an integer(s).


cast


malloc


int *sieve = (int *) malloc(sizeof(int) * length);



This reduces the chance for a human error when/if the data type for sieve is changed.



I would be interested in knowing if there are any "pure" C compilers that would flag this statement as being in error. If so, let me know, so that I can avoid them as their lack of type checking will increase the overall expense of maintaining software.




Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



Would you like to answer one of these unanswered questions instead?

Comments

Popular posts from this blog

Executable numpy error

Trying to Print Gridster Items to PDF without overlapping contents

Hystrix command on request collapser fallback