1

This isn't a specific code question, more of a general question regarding some feedback I've been getting. I write C/C++ code quite frequently (which is not to say I'm any good at it, but that's another story), and occasionally I will cast a pointer, e.g.:

void **result = (void **) malloc(size);

I understand that in this particular case, I do not need it, the compiler should take care of it for me. However, whenever someone else looks at my code, I always seem to get rather snide remarks about the fact that I cast these variables. Is there something inherently wrong with using casting?

wolfPack88
  • 4,163
  • 4
  • 32
  • 47
  • 1
    [This answer](http://stackoverflow.com/a/605858/28169) provides the reasons I know for not casting. Having code that is not needed is in itself a problem, in many cases. I think a cast is very much like SCREAMING in the code, a cast signals that "holy cr*p now I do **this**". Thus, they should never be used when they're not necessary since it loads the code down with a lot of redundant yelling. – unwind May 23 '14 at 14:26
  • 7
    Sure, C doesn't require the cast and C++ doesn't require malloc(). So it is anachronism. Don't write C/C++ code, that language doesn't exist. – Hans Passant May 23 '14 at 14:26
  • Related section in the [isocpp.org FAQ](https://isocpp.org/wiki/faq/coding-standards#pointer-casts). – ComicSansMS May 23 '14 at 14:27
  • 3
    "C/C++ code quite frequently" <- no. You may write both C code and C++ code frequently, but there is no C/C++ "code". – crashmstr May 23 '14 at 14:31

3 Answers3

3

Answer is different for C and C++. In C you should not cast the return value of malloc.
In C++ you must have to cast it.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    In C++, you shouldn't ever use `malloc`. (As for not casting the return value of `malloc` in C, opinions vary. I favor not casting it, but I know some very good C programmers who don't agree---including some at the site where C was invented.) – James Kanze May 23 '14 at 14:45
  • 2
    @JamesKanze: There are plenty of reasons to use `malloc` in C++, including *passing a pointer to a library method which is going to take ownership of the memory and later free it with `free`*. – Eric Lippert May 23 '14 at 15:34
  • @EricLippert Do you know of such a library? I'd say that it was too broken to use. All of the libraries I know have special allocation routines for memory that they may have to delete. And what other reason could there be to use `malloc`, when a type safe alternative exists? – James Kanze May 23 '14 at 16:08
  • 1
    @JamesKanze: You are entirely correct that *good* API design includes custom methods for allocation and deallocation. I assure you that there are many companies that have many legacy libraries that were designed by people who did *not* have a solid background in API design best practices. – Eric Lippert May 23 '14 at 16:12
  • 1
    @JamesKanze: You asked for a second reason. `realloc` can have better performance than the `resize` of `std::vector`; if that turns out to be a hot spot in your program then it is reasonable to use the higher-performance alternative. – Eric Lippert May 23 '14 at 16:15
  • @JamesKanze: A third reason: a team is porting a large legacy library from C to C++. Is changing every `malloc` in the program into `new` really the best use of their time? That seems like the kind of thing you'd want to put off in favour of more important changes that actually impact developer productivity. – Eric Lippert May 23 '14 at 16:17
  • @JamesKanze: Your point is well intended; I'm just pointing out that it is too broad. If you're developing a new application from scratch in C++ then by all means avoid `malloc` like the plague. Many people don't have the opportunity to start from a blank page; they have decades-old legacy C code that can't simply be ignored. – Eric Lippert May 23 '14 at 16:20
  • @Eric Lippert there is an alternative to malloc in that sense- void* operator new (std::size_t size) throw (std::bad_alloc); – Daniel Heilper May 26 '14 at 20:47
2

The title of your question refers to the general usage of casting. From the example on malloc, it seems that your are asking about c-style casting in c++. in c++, you should avoid using c-style casting. instead of (T) (a) Depending on the case, you should use one of the following 4 types of casting:

static_cast <T> (a)
dynamic_cast <T> (a)
const_cast <T> (a)
reinterpret_cast <T> (a)

Using those c++ type conversions, makes the code safer, and more comprehensive.

A great tutorial can be found in herb sutter's: GotW #17-Casts

And also SO post on C++ casts: When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

Community
  • 1
  • 1
Daniel Heilper
  • 1,182
  • 2
  • 17
  • 34
1

Such casts may seem to be useless, but if i'm not wrong, they permit to some compilers to know what to do.
Firstable, it resolves warnings if you're compiling with some flags (And i recommend you to do them), and it makes your code portable. Moreover, it proves that you're really understanding what you're doing.

I just wanna add that you're example (with a malloc) should only be used with C code. For c++, it's recommended to use 'new' ;). The casts in C are used like that :

    int        *tab;

    tab = (int *)malloc(theSize * sizeof(*tab));

This is a clean malloc in C ;)

Guillaume Munsch
  • 1,233
  • 17
  • 37