2017-06-02 2 views
3

Ich bin nicht in der Lage herauszufinden, wie Sie die obige Warnung aus der unteren Zeile des Codes entfernen. Daten sind ein ungültiger Zeiger und als Teil der Rückruffunktion wird eine Zeichenfolge im Datenzeiger empfangen. Da ich den ungültigen Zeiger typecast habe, aber Compiler, der immer noch die Warnung zeigt.In Bezug auf Dereferenzierung 'void *' Zeiger

Es gibt grundsätzlich zwei Warnungen in der unteren Zeile. 1. dereferencing 'void *' Zeiger 2. Adresse des Ausdrucks des Typs unter ‚Leere

service_ind = atoi((const char*)&data[at_response.param[0].start_of_value_index]) ? TRUE:FALSE ; 

Unten benötigt werden Informationen

void * data; 
AT_PARSER_RESPONSE at_response; 

typedef struct 
{ 

/*Other parameters */ 

AT_PARAM param[AT_MAX_NUM_PARAM]; 

}AT_PARSER_RESPONSE 
+1

Bitte zeigen Sie die Definitionen von 'data',' at_response' und was auch immer der Typ von 'at_response.param [0]' ist. – aschepler

+0

Ich denke (immer noch meine erste Tasse Kaffee) die Rangfolge ist nicht das, was Sie denken für '(const char *) & data [at_response.param [0] .start_of_value_index]' (dh Sie können zusätzliche Klammern benötigen), oder dass Sie 'data' in einen gültigen Typ umwandeln müssen, bevor Sie' [] 'verwenden, je nachdem, was' data' * wirklich * ist. – crashmstr

Antwort

5

C11 Zitiert, Kapitel §6.5.3.2

Der unäre Operator * bezeichnet Indirektion. Wenn der Operand auf eine Funktion zeigt, ist das Ergebnis ein Funktionsbezeichner; Wenn es auf ein Objekt zeigt, ist das Ergebnis ein L-Wert, der das Objekt bezeichnet. Wenn der Operand den Typ "Zeiger auf Typ" hat, hat das Ergebnis den Typ "Typ". Wenn dem Zeiger ein ungültiger Wert zugewiesen wurde, ist das Verhalten des unären Operators * undefined.

Also, Ihr Code verursacht undefined behavior.

Auch bezogen, von Kapitel §6.2.5

Der void Typ einen leeren Satz von Werten umfasst; Es ist ein unvollständiger Objekttyp, der nicht abgeschlossen werden kann.

also ein Zeiger auf voidist ein ungültiger Operand für dereferenzieren.


Eine mögliche praktische Fall und die mögliche Lösung

Manchmal für Generika machen wir einen bestimmten Zeiger auf void * werfen, passieren, dass als Argument an eine Funktion, und dann in einer Funktion, die wir werfen es zurück auf den ursprünglichen Typ, basierend auf einigen bekannten Informationen. Dies ist, gemäß Kapitel 6.3.2.3, ein vollkommen gültiger Fall.

[...] Ein Zeiger auf jeder Objekttyp kann in einen Zeiger auf void und zurück konvertiert werden; Das Ergebnis soll gleich dem ursprünglichen Zeiger vergleichen.

Wenn dies der Fall ist, und Sie sind innerhalb der Funktion dereferencing, können Sie den Zeiger werfen entweder

vor Dereferenzierung.

+0

können Sie bitte den Link hinzufügen, aus dem Sie zitiert haben? – CIsForCookies

+1

@CIsForCookies wie ich schon erwähnte, es ist vom C11-Standard, die tatsächlichen sind verkauft, aber Sie können einige Entwurfsversion online, die ziemlich genau sind. :) –

+1

* Sie können jedoch den Zeiger auf einen gültigen Typ vor der Dereferenzierung umwandeln. * Das kann auch undefined Verhalten sein, wie es [strenge Aliasing verletzen kann] (https://stackoverflow.com/questions/98650/what-is -the-strict-aliasing-rule) Wenn du zum Beispiel mit einem 'char *' beginnst, weise es einem 'void *' zu, wirf es dann auf ein 'double *' und versuche es zu dereferenzieren. –

Verwandte Themen