Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C code does not work when coded like C++

Tags:

c++

c

pointers

Hello Developers! I am learning algorithms from Algorithms Design Manual Book by Skiena. There I have the following code:

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

typedef int item_type;

typedef struct{
    item_type item;
    struct list* next;
    }list;

void insert_list(list **l, item_type x){
    list *p;
    p = malloc(sizeof(list));
    p->item = x;
    p->next = *l;
    *l = p;
    }

int main(){
    return 0;
    }

It gives me Warning when compiled:

gcc -Wall -o "test" "test.c" (in directory: /home/akacoder/Desktop/Algorithm_Design_Manual/chapter2) test.c: In function ‘insert_list’: test.c:15: warning: assignment from incompatible pointer type Compilation finished successfully.

But when I rewrite this code as C++:

 #include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef int item_type;

typedef struct{
    item_type item;
    struct list* next;
    }list;

void insert_list(list **l, item_type x){
    list *p;
    p = malloc(sizeof(list));
    p->item = x;
    p->next = *l;
    *l = p;
    }

int main(){
    return 0;
    }

It gives the following:

g++ -Wall -o "chapter2" "chapter2.cpp" (in directory: /home/akacoder/Desktop/Algorithm_Design_Manual/chapter2) chapter2.cpp:15: error: conflicting declaration ‘typedef struct list list’ chapter2.cpp:14: error: ‘struct list’ has a previous declaration as ‘struct list’ chapter2.cpp: In function ‘void insert_list(list**, item_type)’: chapter2.cpp: In function ‘void insert_list(list**, item_type)’: chapter2.cpp:19: error: invalid conversion from ‘void*’ to ‘list*’

Can anyone explain why it is so? And How can I rewrite it in C++?

like image 703
user873286 Avatar asked Mar 22 '26 18:03

user873286


2 Answers

This is because c++ is stricter than c with respect to type conversions.

There are host of other errors in your code. Please note that just putting a c source code, renaming the file as .cpp & compiling using g++ does not make a c source code as c++.

If you are writing a program in c++ please use new & not malloc, doing so you do not need to explicitly type cast as in case of malloc.

like image 150
Alok Save Avatar answered Mar 24 '26 07:03

Alok Save


Your problem in both cases is in the struct definition: struct list *next doesn't refer to the struct you are in the process of declaring. Try this instead:

typedef struct list {
    item_type item;
    struct list* next;
} list;

In addition, in C++ you must cast the void * returned by malloc to the appropriate pointer type (list *), C++ is stricter about these things. Also, BTW, in C++ you can leave off the typedef completely if you want.

The reason for the differing error messages is a difference in the languages.

In C, the compiler knows that struct list * is a pointer to a struct, so it doesn't need to complain that it doesn't actually know what a "struct list" is yet. Later, though, when you try to assign this "struct list *" from a pointer of type "list *" (the type of which is "pointer to an anonymous struct"), it complains about the mismatch.

In C++, a "struct" declaration is more or less equivalent to a "class" declaration (the major difference is in the default visibility of members). Among other things, this means that structs in C++ are more or less automatically typedefed. So when the compiler sees "struct list *next", it takes it as a forward declaration of a class named "list"; then when it finishes the statement and processes the typedef, throws an error because you're trying to typedef something to an identifier that is already (forward-)declared as something else. Then it issues further errors because it doesn't actually know what "list" might be, due to the earlier error.

like image 28
Anomie Avatar answered Mar 24 '26 07:03

Anomie