2016-07-22 33 views
-1

ich kann nicht herausfinden, wie man diese Fehler zu beheben: [Fehler] erwartet ')' vor '< <' tokenSyntaxfehler bitweise Operationen c

Dieser Code ist in einem Makro:

#define SUM_VARS(a, b, c, d)        \ 
    unsigned int *inta = reinterpret_cast<unsigned int *>(&a); \ 
    unsigned int *intb = reinterpret_cast<unsigned int *>(&b); \ 
    unsigned int *intc = reinterpret_cast<unsigned int *>(&c); \ 
    unsigned int *intd = reinterpret_cast<unsigned int *>(&d); \ 

    (((*inta << 24) & 0xFF000000) | ((*intb << 16) & 0x00FF0000) | ((*intc << 8) & 0x0000FF00) | (*intd & 0xFF)) 

Ich verstehe wirklich nicht wo der Fehler sein könnte ... Danke im Voraus!

+0

Das ist keine Art und Weise C! – Olaf

+1

Lösen Sie das Makro von Hand und Sie werden sehen. Warum nicht eine Funktion trotzdem benutzen? – Olaf

+0

Hinzugefügt C++ - Tag - Präprozessor-Makros, Vorlagen (vor allem Reinterpret_cast) - sollte in Ihrem Sinne sein ... – Aconcagua

Antwort

0

Oh - das ist nicht überhaupt retten ...

Stellen Sie sich diese mit SUM_VARS(12, ...) nennen - 12 ist eine Konstante, nicht über eine Speicheradresse und damit nicht Ihr Makro auf &12.

Rufen Sie es mit SUM_VARS(n + 7, ...). Sie erhalten dann – unter Auslassung der Besetzung – unsigned int* inta = &n + 7;. Da n kein Array ist, undefiniertes Verhalten! Auch wenn es nicht ist, werden Sie einen Zeiger auf einen Wert völlig unabhängig von n bekommen ...

Nennen Sie es mit SUM_VARS(c, ...), während c vom Typ char oder short - Sie dann Speicher lesen gerade über die Variable c (undefined Verhalten). OK, auf einer kleinen Endian-Maschine würden Sie die unerwünschten Teile auf einem großen Endian-Gerät maskieren ...

Warum diese Zeiger überhaupt?

Warum nicht einfach

#define SUM_VARS(a, b, c, d) \ 
    ((a) << 24 & 0xff000000) \ 
    |      \ 
    ((b) << 16 & 0x00ff0000) \ 
    |      \ 
    ((c) << 16 & 0x0000ff00) \ 
    |      \ 
    ((d) << 16 & 0x000000ff) 

Beachten Sie die Klammern um a, b, c, d; Sie sind sehr wichtig, um sicherzustellen, dass Ausdrücke, die Operatoren mit niedrigerer Priorität enthalten, vollständig ausgewertet werden, bevor das Bitshift angewendet wird.

Sie werden jedoch viel sicherer sein, wenn Sie eine Funktion dafür verwenden (Olaf wurde bereits empfohlen). Machen Sie es inline, wenn Sie den Overhead eines Funktionsaufrufs gespeichert werden soll (Compiler nicht gezwungen ist, dieser Empfehlung zu folgen, aber mit solch einer einfachen Funktion, höchstwahrscheinlich):

inline unsigned int sumVars(unsigned int a, unsigned int b, unsigned int c, unsigned int d) 
{ 
    return 
     (a << 24 & 0xff000000) 
     | 
     (b << 16 & 0x00ff0000) 
     | 
     (c << 16 & 0x0000ff00) 
     | 
     (d << 16 & 0x000000ff); 
} 

Beachten Sie, dass Sie nicht brauchen, Die inneren Klammern sind wie jetzt, die Ausdrücke werden vor dem Funktionsaufruf ausgewertet.

Wenn Sie weiter gehen wollen, können Sie dies auf eine Template-Funktion erweitern:

template < typename T > 
T sumAll(T t) 
{ 
    return t; 
} 
template < typename T, typename ... Values > 
T sumAll(T t, Values ... values) 
{ 
    return t + sumAll(values...); 
}