0

The question on following snippet of code

  char *p = malloc(10);

When i compile it with gcc with any -std=, this does compile well.

But with g++ with any -std= this does produce error:

w.c:4:21: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
  char *p = malloc(10);

Why behavior is differing? I thought all lines which compile in C should compile with C++ compiler, too. Is there any standard requirements for this?

Galimov Albert
  • 7,269
  • 1
  • 24
  • 50

4 Answers4

5

Because you compile as C with gcc and as C++ with g++. Those are different languages.

C++ is more strongly typed as far as implicit conversions from void* go.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 6
    "C++ has stricter type checking" is an urban legend... the difference in this case is that C has implicit conversion from `void *` to other object pointer types , nothing more and nothing less. Both languages are statically typed, and both languages offer the conversion - just one language requires a cast. – M.M Feb 15 '16 at 13:22
  • @M.M, to be pedantic for a second, requiring a cast *is* a stricter position on language designers part. And you most definitely shouldn't take the first half of that sentence without the second. – StoryTeller - Unslander Monica Feb 15 '16 at 13:26
  • 1
    @StoryTeller I agree with you but, to be just as pedantic, the requirement for an explicit cast in this case would normally described as an example of _stronger typing_ rather than _stricter type checking_, I think. – davmac Feb 15 '16 at 13:34
  • @davmac, point taken, and corrected. – StoryTeller - Unslander Monica Feb 15 '16 at 13:34
  • @M.M statically typing is not related with strong typing. – too honest for this site Feb 15 '16 at 14:00
4

First of all it is explicit in specification of those 2 languages and it is enough for compilers to conform to that.

But there are good reasons why C allows implicit conversion from pointer to any to void * and back while C++ disallows it. As C as no inheritance support, all kind of polymorphism requires the use of void * pointers. So conversion to and from void * is assumed to be a common use case. Also as you have no static, dynamic or const cast in C, if you want to keep constness of a pointer, you would have to repeat it on each void *conversion.

But C++ does have inheritance, static and dynamic cast. So conversion from pointer to any to void * and back has less common use cases and for that reason must be explicit. And last but not least, the usage of new hides the call to malloc and directly gives a pointer to the proper type avoiding the cast form void * each time you create a dynamic object.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • More importantly IMHO, C++ has `new` which renders `malloc` - and any associated type conversion, explicit or otherwise - redundant. – davmac Feb 15 '16 at 13:44
  • @davmac: not redundant, as `new` itself may use `malloc`. It provides a higher abstraction by also calling the constructor, etc.. – too honest for this site Feb 15 '16 at 14:03
  • @Olaf redundant from the point of the view of the application programmer. (And btw you can use `new char [xxx]` if you want to allocate memory without calling constructors - so `new` gives you everything `malloc` does and more). – davmac Feb 15 '16 at 14:11
  • @Olaf grammar/typo error in your comment? I don't understand it. Anyway, my point is that you can use `new`/`delete` instead of `malloc`/`free` universally (or almost so). They both allocate storage. In this sense, there is redundancy. – davmac Feb 15 '16 at 15:04
  • @davmac: Sorry, retry: There's _more_ to "application programming" than PCs. – too honest for this site Feb 15 '16 at 15:09
  • @Olaf Ok. My point was that an application programmer doesn't need to know or care whether `new` is actually implemented via `malloc` (in response to your "not redundant, as new itself may use malloc"). I wasn't referring to PCs in particular. I'm talking about what the programmer uses, not what happens under the surface. – davmac Feb 15 '16 at 15:16
  • @davmac: While I generally agree C++ should not use `malloc`, there might be reasons to use `malloc` in C++ on an embedded system. Using `new char [xxx]` is not really a better solution. – too honest for this site Feb 15 '16 at 15:25
  • @davmac: IMHO, a typical use case for using malloc in a C++ program (except for some embedded systems that could have *special* implementations) is when you have to be called through a C API that requires a malloc'ed block of memory that will be free'd after use. Of course, `new char[x]` could be used, but if you know that `free` will be directly called, it is better to use `malloc`. Symetrically, you should use `free` if an object has been created with a direct call to `malloc` in a C library. – Serge Ballesta Feb 15 '16 at 15:37
  • @Olaf (and Serge) Once again, it's redundancy from the perspective that they both do the same thing. Yes, there might be systems-level reasons for using `malloc` over `new`, and yes, interface considerations (eg when using a C library) need to be respected. But at the level of the language itself, there is no need for `malloc` in C++. It is there solely to maintain C compatibility. – davmac Feb 15 '16 at 15:43
  • @davmac: fully agree with your last comment. – Serge Ballesta Feb 15 '16 at 15:45
  • @davmac: finally: embedded systems is not the same as "system level". And maintaining C compatibility is nonsense, because the languages themselves are not compatible. But I agree that almost all usages in C++ are just a signal of bad design. – too honest for this site Feb 15 '16 at 15:45
  • @Olaf you are nit-picking to the extreme. Please read "C compatibility" as "compatibility with some C code". Of course the languages are not fully compatible. Regarding "system level", if you are choosing `malloc` vs `new` because it is better on your target _system_ then it is a _system level_ concern that drives your decision. – davmac Feb 15 '16 at 15:52
2

C++ doesn't do implicit conversion of void* ...You will have to explicitly do it

char *p = static_cast<char*>(malloc(10));

or

char *p = reinterpret_cast<char*>(malloc(10));
WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
  • 3
    @YSC I don't see the problem with `static_cast` and think it should be preferred in this case. See http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used – davmac Feb 15 '16 at 13:21
  • BTW, why static_cast is not correct ? – Galimov Albert Feb 15 '16 at 13:22
0

Although, many people think that everything done in C can be done in C++, with the nearly same code is wrong. C++ is not a superset of C. Both are different.

Thus, the compilers will be different and g++ is used for C++ while gcc is used for C.

Check this: What is the difference between g++ and gcc?

Community
  • 1
  • 1
Box Box Box Box
  • 5,094
  • 10
  • 49
  • 67