1

In C, if I have two types of pointers:

typeB *q;
typeA *p; 

int the following, is it unnecessary to put an explicit cast (typeA *)

1    p= q       is fine, no need to use p = (typeA  *)q;

2    define: void func(typeA *p){}

     call:  func(q);  is fine, no need to use func((typeA  *)q)

3    p=malloc(sizeof(typeA));   is fine, no need to use p=(typeA  *)malloc(sizeof(typeA))

besides, is C++ the same or not?

thanks!

misteryes
  • 2,167
  • 4
  • 32
  • 58
  • c++ has inheritance making some things allowable that may not be in c. But the one major thing to be wary of that is different between c and c++ is this... for the variables `typeA * a; typeB * b; void * v` the result of `a=b` can be different to `v=b;a=v`. This happens with multiple inheritance in c++. Basically `void *` removes c++'s ability to track inheritance properly. – Philip Couling Jun 12 '13 at 12:28
  • 1
    you may look at this [GOTW about casts](http://www.gotw.ca/gotw/017.htm) – loic Jun 12 '13 at 12:33
  • 1
    [Do I cast the result of malloc?](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858) – Grijesh Chauhan Jun 12 '13 at 13:27

3 Answers3

5

I'll assume that they are unrelated types. If they are both aliases for the same type, then pointers to one can be implicitly converted to pointers to the other.

  1. No; in both languages, you need a cast to convert between unrelated pointer types. In C++, it is fine if typeA is a base class of typeB.

  2. Exactly the same as the first - both are trying to initialise a typeA* from a typeB*.

  3. Fine in C; void* can be implicitly converted to any object pointer type. That conversion is not allowed in C++; but you usually shouldn't be using malloc anyway.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
4

If you use TypeB * where TypeA * is expected, then you always need the cast. In C, there are two exceptions: conversion from and to void * is implicit (no cast needed) if the other type is a data pointer type. It's only under POSIX that void * is also implicitly compatible with function pointer types.

In C++, however, only conversion to void * is implicit, so assigning T *p = <expression of type void *>; still needs the cast.

Another difference is that in C++, if TypeA and TypeB are class (or struct) types, and TypeB inherits from TypeA then conversion from TypeB * to TypeA * ("downcasting") is again implicit (no cast needed). Of course this doesn't work backwards ("upcasting").

All in all, you don't cast the return value of malloc(), because:

  • in C is not required;

  • In C++ it would be required but in C++ you don't use malloc() anyway.

  • "All in all, you don't cast the return value of malloc(), because: in C is not required; In C++ it would be required but in C++ you don't use malloc() anyway. " Best quote about, I ever heared. – dhein Mar 05 '15 at 12:58
0

for the first two cases you need to typecast(in c and c++ both) because they are not void type so it is required to cast them explicitly.

For the third case malloc is returning void pointer which will change itself according to casting.So no need for explicit typecasting here(in c).

Dayal rai
  • 6,548
  • 22
  • 29