2014-04-16 9 views
10

I-Code, der anders zwischen GCC und Atmel Studio ausgeführt wird:C Ausdruck unterschiedlich auf zwei verschiedene Compiler Auswertung

uint32_t tc = 107900; 
int8_t m = 59; 

tc = tc - (m*1800); 

auf GCC, ist das Ergebnis in tc 1700, wie vorgesehen.

Mit AtmelStudio ist das Ergebnis in tc 132772, was nicht korrekt ist.

Das Problem scheint zu sein, dass der m*1800 Begriff mit der begrenzten Genauigkeit von m mit AtmelStudio berechnet wird.

Meine Frage ist, welcher Compiler es richtig macht?

Vielen Dank.

+4

Ich würde mir vorstellen, dass Casting 'm' zu' uint32_t' in der Ausdruck (dh 'tc = tc - ((uint32_t) m * 1800)') würde die gewünschten Ergebnisse erzeugen, aber ich bin mir nicht sicher, dass es erforderlich ist nach den Spezifikationen der C-Sprache. –

+1

... oder verwenden Sie '(m * 1800L)', da das arithmetische Produkt von 59 * 1800 nicht in den _minimum_ angegebenen Bereich von -32767 bis +32767 passt, aber in das angegebene _minimum_ C passt Angebot. – chux

+0

Offensichtlich verwendet dieser Compiler standardmäßig 16-Bit-Ganzzahlen. Erwartetes Verhalten –

Antwort

6

Beide tun es richtig. Der Ausdruck m * 1800 wird als Typ int berechnet. Wenn int 32 Bit ist, dann wird es 106200 sein. Wenn int 16 Bits ist, was eine vollkommen akzeptable Möglichkeit ist, einen C-Compiler zu implementieren, dann ist es -24872.

+2

Eigentlich ist es im letzteren Fall undefiniert. –

+0

Nicht perfekt, nur Standard, aber es ist genug für eine +1 :-) – peterh

+0

Danke, also hat es mit der Standard-Typ-Größe der Konstante zu tun. – NXT

10

Es scheint, dass bei AtmelStudio int 16-Bit ist, also m*1800 überläuft, undefiniertes Verhalten aufrufen. In Ihrem Fall war das Verhalten, das der Compiler gab, wahrscheinlich eine Reduktion von Modulo 65536 in den Bereich [-32768,32767], was -24872 ergibt. Dann tc - (m*1800) ist 132772.

Um dies zu vermeiden, müssen Sie Überlauf werfen entweder m oder 1800 zu uint32_t oder eine andere Art (z long), wo das Ergebnis wird nicht vor der Multiplikation zu tun.

Verwandte Themen