2012-04-02 10 views
0

Ich möchte ein Projekt mit GCC zu IAR-Compiler portieren, aber IAR beschwert sich auf mehrere Funktionen mit void * als formaler Parameter.Warum IAR-Fehler auf void *

struct 
{ 
    uint16_t ConnectionHandle; 
    uint8_t Reason; 
}DisconnectParams; 

der Funktionsprototyp ist

bool Bluetooth_HCI_SendControlPacket(BT_StackConfig_t* const StackState, 
            const uint16_t OpCode, 
            const uint8_t Length, 
            const void* Data); 

und die Verwendung ist:

Bluetooth_HCI_SendControlPacket(StackState, (OGF_LINK_CONTROL | OCF_LINK_CONTROL_DISCONNECT), sizeof(DisconnectParams), &DisconnectParams); 

beschweren Hier Fehler [Pe167]: Argument vom Typ "struct *" ist nicht kompatibel mit dem Parameter von Typ "void const *"

Und ein anderer Ort

static inline void SDP_WriteData8(void** BufferPos,const uint8_t Data) 
{ 
*((uint8_t*)*BufferPos) = Data; 
*BufferPos += sizeof(uint8_t); 
} 

Fehler [Pe852]: Ausdruck muss ein Zeiger auf einen vollständigen Objekttyp sein. Wie ich weiß, kann void * jeden Zeiger annehmen, Wie man den Code ändert, um diese Fehler zu entfernen? Vielen Dank!

Chris

+0

Können Sie weitere Details zu IAR-Version und Projekteinstellungen angeben? Ich kann Ihr erstes Problem mit IAR 5.40 nicht replizieren. – tinman

+0

Mein IAR ist EWARM 6.30.1, Einstellung ist C99 und erlauben VLA (variable Länge Array), aber die - vla scheint keine Wirkung, weil es immer noch beschweren, dass Ausdruck muss einen konstanten Wert haben, wenn ich eine variable Array definieren uint8_t Data DataLen]; – user1308274

+0

Was ist das Zielgerät? –

Antwort

3

In Bezug auf Ihre zweite Frage, dass Code ist ungültig, weil, was Sie haben ein void * ist und Sie versuchen, es durch sizeof zu erhöhen (uint8_t) (Ich gehe davon aus 1). Das entspricht:

void *p; 
p += 1; 

Sie nicht Zeiger arithmatic auf einem Zeiger ausführen kann, die einen unvollständigen Typ hat, da der Compiler nicht weiß, wie der Wert durch zu erhöhen (nicht vergessen, es geht durch die Größe des anvisierten Objekts) .

Wahrscheinlich wollten Sie den Zeiger vor dem Inkrementieren auf einen Zeiger uint8_t setzen.

+0

Danke für Ihre Antwort. OK, ich habe deine Antwort verstanden. Aber eine andere Frage ist, warum gcc sie übersetzen kann. – user1308274

+0

Vielleicht gibt es eine gcc-Erweiterung, die automatisch annimmt, dass Sie in Byte-Schritten hinzufügen möchten, wenn Sie dem leeren Zeiger Werte hinzufügen? Sorry, ich weiß es nicht genau, da ich gcc nicht benutze. – tinman

+0

GCC hat eine solche Erweiterung: http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Pointer-Arith.html#Pointer-Arith –

0
#ifdef I_JUST_LOVE_MYSTERIOUS_COMPILER_ERRORS 
    struct 
    { 
    uint16_t ConnectionHandle; 
    uint8_t Reason; 
    }DisconnectParams; 
#else 
    typedef struct 
    { 
    uint16_t ConnectionHandle; 
    uint8_t Reason; 
    }DisconnectParams_t; 

    DisconnectParams_t DisconnectParams; 
#endif 
+0

Hilft das wirklich? Wenn ja, kann ich nicht verstehen warum - wie kann der Compiler die Adresse eines Typs als Argument für einen Funktionsaufruf akzeptieren? Wie kann es das überhaupt beurteilen? –

+0

@MichaelBurr Ich habe keine Ahnung, es gibt zu wenig Informationen zu erzählen. Es scheint jedoch eines der wahrscheinlichen Probleme zu sein. Versuche es. – Lundin

+0

@lundin - es wird nicht funktionieren: 'struct {...} DisconnectParams' definiert eine namenlose Struktur und deklariert gleichzeitig eine Variable (namens DisconnectParams) dieses Typs; 'typedef struct {...} DisconnectParams' definiert eine namenlose Struktur und deklariert ein Synonym für diesen Typ (mit dem Namen DisconnectParams). DisconnectParams ist im ersten Fall eine Variable, im zweiten ein Typ. Im zweiten Fall ist der Aufruf von 'Bluetooth_HCI_SendControlPacket' mit' & DisconnectParams' definitiv ein Compilerfehler ... – Attila

Verwandte Themen