2013-08-08 7 views
7
gewünschten

Ich versuche, den richtigen Weg, um herauszufinden, eine ganze Zahl von einem void * Funktionsaufruf innerhalb C. zurückzukehrenWarnung: Rückkehr macht Zeiger von Ganzzahl ohne Guss gibt aber integer als

dh ..

#include <stdio.h> 

void *myfunction() { 
int x = 5; 
return x; 
} 

int main() { 
    printf("%d\n", myfunction()); 
    return 0; 
} 

Aber ich bekomme immer wieder:

Warnung: Rückkehr macht Zeiger von Ganzzahl ohne Guss

Gibt es eine Besetzung, die ich tun muss, damit dies funktioniert? Es scheint x ohne Problem zurückzugeben, die echte myfunction gibt Zeiger auf Strukturen und Zeichenfolgen zurück, die alle wie erwartet funktionieren.

+7

Warum tust du das? – orlp

+4

'myfunction' Rückgabetyp ist' void * 'aber der Typ von' x' ist 'int'. Warum möchtest du es funktionieren lassen? Was ist die wahre Funktion, mit der Sie es zu tun haben? – Mahesh

+0

Ein guter Grund: Code zu pflegen, den jemand anderes getan hat. –

Antwort

5

Es ist nicht offensichtlich, was Sie hier erreichen wollen, aber ich nehme an, Sie versuchen, einige Zeigerarithmetik mit x zu tun, und möchten, dass x eine ganze Zahl für diese Arithmetik ist, aber ein void-Zeiger auf return . Ohne darauf einzugehen, warum dies sinnvoll ist oder nicht, können Sie die Warnung eliminieren, indem Sie x explizit in einen void-Zeiger umwandeln.

Dies wird höchstwahrscheinlich eine weitere Warnung auslösen, abhängig davon, wie Ihr System Zeiger implementiert. Möglicherweise müssen Sie einen langen anstelle eines int verwenden.

void *myfunction() { 
long x = 5; 
return (void *)x; 
} 
+0

Dies scheint die Warnung verschwinden zu lassen, und ich würde gerne wissen, warum das funktioniert oder ob dies tatsächlich undefiniertes Verhalten ist. Jede Antwort hat für mich einen Sinn ergeben, aber das macht genau das, was ich versucht habe zu tun. – user2662982

+0

Die anderen Antworten nehmen an, dass Sie einen Zeiger auf die Ganzzahl zurückgeben möchten, die sich von der Ganzzahl als Zeiger unterscheidet. Die Warnung, die du bekommen hast, war sicherzustellen, dass du feststellst, dass du einen Int in einen leeren Zeiger verwandelst. Es ist perfekt, einen Zeiger auf einen langen Zeiger zu setzen, obwohl es oft einfacher ist, nur mit Zeigern zu arbeiten, um Verwirrung zu vermeiden. Da die Leerer-Zeiger-Arithmetik unzulässig ist, sollten Sie einen char * -Zeiger verwenden, der sich während der Arithmetik als Int verhält, da seine Größe ein Byte ist. – user2663103

+1

Es mag erwähnenswert sein, dass es eine Plattform geben könnte, bei der ein "int" breiter als ein "void *" ist, so dass die Umwandlung von ersteren in letztere Bits verlieren würde. Wenn also das Speichern einer ganzen Zahl in einer Zeigervariablen wirklich notwendig ist, könnte man die ganze Zahl als intptr_t x; oder uintptr_t x; betrachten, da vom C-Standard "intptr_t" und "uintptr_t" garantiert werden, um in einen Zeiger zu passen Variable. – alk

1

Ein void * ist ein Zeiger auf irgendetwas, Sie müssen eine Adresse zurückgeben.

void * myfunction() { 
    int * x = malloc(sizeof(int)); 
    *x=5; 
    return x; 
} 

Davon abgesehen sollten Sie eine void * für einen int nicht zurückkehren müssen, sollten Sie int * zurückkehren besser oder auch nur int

+1

Ich verstehe Ihre Absicht, aber es gibt keinen 'neuen' Operator in' C'. – Mahesh

+0

@Mahesh whoops, achtete nicht auf die Tags – aaronman

+0

Was auch immer, er kann es immer ändern in 'malloc (sizeof (int))'. – Raptor

0

Obwohl Sie die einfachste Weg, dies wäre zu tun, denken würde:

void *myfunction() { 
    int x = 5; 
    return &x; // wrong 
} 

ist dies tatsächlich nicht definiertes Verhalten, da x auf dem Stapel zugeordnet ist, und der Stapelrahmen wird als „aufgerollt“, wenn die Funktion zurückkehrt. Die alberne, aber korrekte Art ist:

void *myfunction() { 
    int *x = malloc(sizeof(int)); 
    *x = 5; 
    return x; 
} 

Bitte nie, jemals Code wie diese schreiben, obwohl.

+1

Sie sollten einen Weg finden, um den gesamten ersten Teil in leuchtend rot mit einem x dadurch – aaronman

+0

Ich bin verwirrt, warum ist es dass ich eine Ganzzahl als void-Zeiger beim Senden an eine andere Funktion umwandeln kann, aber ich kann eine Ganzzahl nicht als Void-Zeiger, wenn es als Rückgabewert erhalten? – user2662982

+0

@ user2662982 Die ganze Zahl wird auf dem Stapel gespeichert. Wenn Sie eine Funktion aufrufen, bleibt der "Stack-Frame" der ursprünglichen Funktion (Speicher für Variablen) erhalten, und die neue Funktion erhält Platz "oben" auf dem alten Stack-Frame. Sobald die Funktion jedoch zurückkehrt, gibt es keine Garantie, dass die Variablen beibehalten werden, da der Platz "oben" für andere Variablen verwendet werden könnte. Vielleicht möchten Sie mehr über den * Stack * und den * Heap * lesen. –

0

ich diese Quelle mit gcc -pedantic zusammengestellt:

#include <stdio.h> 

void *myfunction() { 
    size_t x = 5; 
    return (void*)x; 
} 

int main() { 
    printf("%d\n", *(int*)myfunction()); 
    return 0; 
} 

Es gibt keine Warnungen ist

Verwandte Themen