2013-05-28 21 views
6

Ho un programma C che genera un errore:conversione non valida da 'void *' a 'nodo *' [-fpermissive]

invalid conversion from 'void*' to 'node*' [-fpermissive] 

Ecco il mio codice:

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

struct node 
{ 
    int data; 
    struct node* next; 
}; 

struct node* onetwothree(); 

int main() 
{ 
    struct node* ptr; 
    ptr = onetwothree(); 
    return 0; 
} 

struct node* onetwothree() 
{ 
    struct node* head; 
    struct node* temp; 
    head = malloc(sizeof(struct node)); 
    temp = head; 
    for(int i=1; i<=3; i++) 
    { 
     temp->data = i; 
     if(i<3) 
      temp=temp->next; 
     else 
      temp->next = NULL; 
    } 
    return head; 
} 

Che cosa sono io fare male?

+2

Quanto ne sei sicuro che si sta compilando questo come codice C e non il codice C++? – nos

+1

@Sildoreth Per favore ** non ** modificare i post per modificare lo stile di codifica in base alle proprie preferenze soggettive. Questo è solo vandalismo e non aiuta nessuno. La tua modifica non dovrebbe mai essere stata approvata. Modifica rollback. – Lundin

+0

Detto questo, l'indizione di questo post è orribilmente incoerente e ha bisogno di una soluzione. Una modifica che modifica semplicemente l'indentazione va bene. – Lundin

risposta

15

In C, un void* è implicito convertibile in T* dove T è di qualsiasi tipo. Dalla sezione 6.3.2.3 Puntatori dello standard C99:

A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

malloc() restituisce un void* ed è assegnabile, senza fusione a head, un struct node*. Questo non è vero in C++, quindi ho il sospetto che un compilatore C++ venga usato per compilare questo codice C.

Ad esempio:

#include <stdlib.h> 

int main() 
{ 
    int* i = malloc(sizeof(*i)); 
    return 0; 
} 

se compilato con:

gcc -Wall -Werror -pedantic -std=c99 -pthread main.c -o main

emette alcun errore. Se compilato con:

g++ -Wall -Werror -pedantic -std=c++11 -pthread main.cpp -o main

emette:

main.cpp: In function 'int main()': main.cpp:5:31: error: invalid conversion from 'void*' to 'int*' [-fpermissive]


Inoltre, la funzione onetwothree() non alloca memoria correttamente. Si assegna un solo struct node:

head = malloc(sizeof(struct node)); 

e poi, eventualmente, dereferenziazioni head->next->next che è un comportamento indefinito. È necessario un singolo malloc() per ogni struct node. Ricorda di free() che cosa era malloc() d.

+0

non riesco a ricordare i dettagli, ma i puntatori pensati per funzioni e dati non erano intercambiabili in c? è sbagliato? dovrebbe essere "qualsiasi tipo di dati"? –

+0

@andrewcooke Corretto. Tuttavia, sulle nostre piattaforme server/desktop comuni lo sono e posix sembra richiedere implicitamente almeno che i puntatori di void * e di funzione siano intercambiabili. – nos

+0

@andrewcooke, aggiornerò la risposta con la sezione pertinente dallo standard C99, che afferma _questo tipo di oggetto o incompleto. – hmjd

2

Stai avendo questo avviso/errore perché si utilizza malloc (che restituisce un void*) per inizializzare una struttura di tipo node* senza fare un cast esplicito.

per sbarazzarsi di questo errore si potrebbe modificare il codice in questo modo:

head = (struct node *)malloc(sizeof(struct node)); 

oppure si potrebbe anche aggiungere il flag "-fpermissive" per il compilatore che verrà poi ignorare questi errori.

EDIT: Ma sì, non ho pensato al fatto che questo non dovrebbe accadere in un compilatore C in ogni modo

+4

-1, risposta errata. Questo è C e non C++, in C 'void *' si converte facilmente in qualsiasi puntatore a un tipo di dati. –

+0

Sì, ho modificato la mia risposta, non ci ho pensato, mi dispiace. –

+0

@JensGustedt se compilato con C++ comilper allora anche il codice C mostrerà questo errore, quindi non è davvero una risposta sbagliata e vale meno di un downvote. – A4L

Problemi correlati