2
typedef struct node node;

//  LinkedList data structure to hold characters.
struct node {
    char character;
    node *link;
};

Later I try:

node *tmp = malloc(sizeof (node));

And I get an error in my text editor saying:

clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
error: cannot initialize a variable of type 'node *' with an rvalue of type 'void *'
            node *tmp = malloc(sizeof (node));
                  ^     ~~~~~~~~~~~~~~~~~~~~~
    1 error generated.
    [Finished in 0.1s with exit code 1]

I get the same error in Xcode, but it works and compiles fine using gcc in Terminal. How come?

Thanks in advance.

Kninnug
  • 7,992
  • 1
  • 30
  • 42
Mickey
  • 117
  • 1
  • 10

1 Answers1

1

malloc returns type void *. What you want is to cast a raw buffer region of void * to node *.

By adding (node*) cast before malloc, you are using C style cast. In GCC, the compiler will auto match un-casted memory to node*. This is not a standard behavior for C++ compilers though. At the same time, if you turn on warnings by add -Wall option, you should see a warning for the missed cast.

CLang is little more strict than GCC when it comes to this. It basically dose not allow anything not within standard and Apple derived standards.

To properly fix this, you need to

  1. add (node *) cast before malloc
  2. wrap the whole code body with extern "C" { ... } clause.
  3. use #ifdef to determine if the compiler is c++ compiler if desired.

This will ensure that compiler understand that the code is c code and the type cast will be performed properly.

Xephon
  • 393
  • 1
  • 12
  • You should not cast the return from malloc in c: http://www.velocityreviews.com/forums/t317038-why-is-casting-malloc-a-bad-thing.html – harald Mar 14 '14 at 17:52
  • 1
    @Xephon: You wrote, "This is not a standard behavior though"; that is not correct. Refer to the [online C standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), 6.5.16.1/1 - "the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of `void`, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;" – John Bode Mar 14 '14 at 18:40
  • @JohnBode Sorry for the confusion. I meant that this is not a standard behavior for a C++ compiler. I've changed the post to reflect that. – Xephon Mar 14 '14 at 20:18