5

The following code gives the error "error: invalid conversion from void* to char* [-fpermissive]"

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(){
    char *t = malloc(20);
}

However, casting the result of malloc solves the problem. But I cannot understand why as this question says that casting the result of malloc is not needed.

Community
  • 1
  • 1
Nikunj Banka
  • 11,117
  • 16
  • 74
  • 112
  • possible duplicate of [invalid conversion from 'void\*' to 'node\*' \[-fpermissive\]](http://stackoverflow.com/questions/16793587/invalid-conversion-from-void-to-node-fpermissive) – hmjd May 29 '13 at 13:41
  • possible duplicate of [How can I do this type conversion?](http://stackoverflow.com/q/16751004/315052). – jxh May 29 '13 at 13:46

5 Answers5

16

You compiled this C program using a C++ compiler. It is necessary to cast the result of malloc in C++, but not in C.

zwol
  • 135,547
  • 38
  • 252
  • 361
5

Is it possible that you are compiling the code as c++? In c++ the cast would be required.

Peter
  • 393
  • 3
  • 15
2

In your case,

malloc(20);

will assign memory as required and will return a pointer which can be assigned to any pointer, as explained in this document

As pointed out, you probably are using C++ compiler, because in C its actually considered a bad practice to cast result of malloc.

Community
  • 1
  • 1
Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
0

You need to explicitly make a cast there. malloc returns pointer to void i.e. void *.

If you compile code with C, void * will be promoted to type * as required but this is not true on c++

nurd_droid
  • 64
  • 4
  • 3
    No he *doesn't* need a cast; he just needs to compile his C code with a C compiler. (If the question had been tagged C++, your answer would have been more correct, though using `new` rather than `malloc()` would have been better advice.) – Keith Thompson Aug 03 '13 at 21:56
0

Thank-you for this clear and explicit question, about a topic that seems to generate a lot of opinions. I have run four versions of your code using Eclipse/Microsoft C compiler on a source file named main.c.

Case 1:

  #include<stdlib.h>
  int main(){
      char *t = malloc(20);
  }

Case 1 compiled with no errors and there was no casting of malloc.

Case 2:

   //#include<stdlib.h>  <<== stdlib.h commented out!!
   int main(){
      char *t = malloc(20);
   }

Case 2, received the following warning:

   ..\main.c(14) : warning C4047: 'initializing' : 'char *' differs in levels of indirection from 'int'

The reason for this is that malloc is defined in <stdlib.h>, when the prototype for a function is not provided then C assumes that the function is returning an int, yet t is a char * thus the warning.

Case 3:

   //#include<stdlib.h>  <<== stdlib.h commented out
   int main(){
      char *t = (char *) malloc(20);
   }

This compiled with no errors, but only because the cast statement (char *) told the compiler that the results of malloc could indeed be assigned to t.

Finally, Case 4:

   #include<stdlib.h>
   int main(){
      char *t = (char *) malloc(20);
   }

This also ran with no compilation or run-time errors. And Case 4 is the point of many opinions. The cast statement (char *) in Case 4 can be considered extraneous. However, it does provide information to the human. In this case the C compiler converts a void * to a char * just like it would do without the cast!!

Case 4 is cheaper to maintain over the lifetime of the code, in that it lessens the chance that a human will NOT understand the intent of the code.

JackCColeman
  • 3,777
  • 1
  • 15
  • 21
  • 1
    Your cases 2 and 3 (without `#include ` are invalid. In C99 or later, calling a function (including `malloc`) with no visible declaration has undefined behavior. Prior to C99, both cases 2 and 3 have undefined behavior; the compiler *assumes* that `malloc` returns `int`, but in fact it returns `void*`. Case 1 is correct. Case 4 is not easier to maintain; if the type of `t` changes, you have to update *both* occurrences of `char*`. – Keith Thompson Aug 03 '13 at 21:59
  • The expense of maintaining code is not how many changes have to be made. It is the risk of the programmer not understanding the program. Explicitly casting ensures that the human reading the code understands what was intended by the original programmer. – JackCColeman Aug 04 '13 at 20:19
  • I'd say that understandability *to someone who knows the language well* is the most important factor. An experienced C programmer should know that casting the result of `malloc` is not necessary. http://c-faq.com/malloc/mallocnocast.html – Keith Thompson Aug 04 '13 at 20:22