Die obige Bitverschiebung hat einen Fehler:
unsigned short p = (packetBuffer[1] << 8) | packetBuffer[2];
wenn packetBuffer
in Bytes (8 Bits breit) ist, kann und wird die obige Verschiebung zu packetBuffer
in eine Null verwandelt, so dass Sie nur noch packetBuffer[2];
Trotzdem wird dies immer noch den Zeigern vorgezogen. Um das obige Problem zu vermeiden, verschwende ich ein paar Zeilen Code (anders als ganz-literal-zero-Optimierung) es führt zu den gleichen Maschinencode:
unsigned short p;
p = packetBuffer[1]; p <<= 8; p |= packetBuffer[2];
Oder um einige Taktzyklen zu sparen und die Bits nicht nach hinten zu verschieben:
unsigned short p;
p = (((unsigned short)packetBuffer[1])<<8) | packetBuffer[2];
Mit Zeigern muss man vorsichtig sein, der Optimierer wird einen beißen, ebenso wie mit Speicherausrichtungen und einer langen Liste anderer Probleme. Ja, wenn man es richtig macht, ist es schneller, wenn man es falsch macht, kann der Fehler lange verweilen und dann auftreten, wenn man es am wenigsten möchte.
Angenommen, Sie waren faul und wollten eine 16-Bit-Mathematik mit einem 8-Bit-Array durchführen. (Little Endian)
unsigned short *s;
unsigned char b[10];
s=(unsigned short *)&b[0];
if(b[0]&7)
{
*s = *s+8;
*s &= ~7;
}
do_something_With(b);
*s=*s+8;
do_something_With(b);
*s=*s+8;
do_something_With(b);
Es gibt keine Garantie dafür, dass ein vollkommen fehlerfreier Compiler den von Ihnen erwarteten Code erzeugt. Das Byte-Array b
die an den do_something_with()
Funktion darf niemals von der *s
Operationen. Nichts im obigen Code besagt, dass dies der Fall sein sollte. Wenn Sie Ihren Code nicht optimieren, werden Sie dieses Problem vielleicht nie sehen (bis jemand optimiert oder Compiler oder Compiler-Versionen ändert). Wenn Sie einen Debugger verwenden, werden Sie dieses Problem möglicherweise nie bemerken (bis es zu spät ist).
Der Compiler sieht keinen Zusammenhang zwischen s und b, es handelt sich um zwei völlig verschiedene Elemente. Der Optimierer kann beschließen, nicht zu schreiben *s
zurück in den Speicher, weil es sieht, dass *s
hat eine Reihe von Operationen, so dass es diesen Wert in einem Register halten und erst am Ende (wenn überhaupt) im Speicher speichern kann.
Es gibt drei grundlegende Möglichkeiten, das oben beschriebene Zeigerproblem zu lösen:
- Erklären Sie
s
als flüchtig.
- Verwenden Sie eine Gewerkschaft.
- Verwenden Sie eine oder mehrere Funktionen, wenn Sie den Typ wechseln.
0 Stimmen
Was muss dieser kerl jetzt von uns c++ programmierern denken. jeder hat eine andere "richtige" lösung :D
0 Stimmen
Nun, er könnte damit meinen, dass wir C++-Anwender ein schlaues Völkchen sind und die Regeln nach Belieben ändern. Mu ha haaa.
0 Stimmen
Enthält die Eingabe eine Zeichenkette mit Werten von '0'-'9' oder enthält sie Bytes mit Werten von 0-255? Die Dokumentation sagt String, aber es macht keinen Sinn, in diesem Fall mit 256 zu multiplizieren.
0 Stimmen
Ich vermute, dass sie die Binärzahlen 1 bis 9 enthält.