Forum: Compiler & IDEs Merkwürdige Compilerwarnung


von Falk B. (falk)


Lesenswert?

Hallo liebe Gemeinde,

ich hab ein kleines Problem mit einer Compilerwarnung. Folgender 
Codeausschnitt (gekürzt) erzeugt eine Warnung, das Programm läuft auch 
nicht korrekt.

1
#define F_CPU 8000000L
2
3
#define T_HALF_PERIOD3       2000   // us -> 4000us period = 250 Hz
4
#define CNT_HALF_PERIOD    (T_HALF_PERIOD3 * F_CPU / 4 / 1000000)   // compiler warning and program malfunction
5
#define CNT_1_US             (F_CPU / 4 / 1000000)
6
7
  int t_gate, t_low=0, t_high;
8
9
      for(t_gate = 20*CNT_1_US; t_gate < 500*CNT_1_US; t_gate += 4*CNT_1_US) {
10
        t_low = CNT_HALF_PERIOD - 2*t_gate;
11
        GATE_ON;
12
        _delay_loop_2(20*CNT_1_US);    
13
        ZEROCROSS_OFF;
14
        _delay_loop_2(t_gate);
15
        GATE_OFF;
16
        _delay_loop_2(t_low);
17
        GATE_ON;
18
        _delay_loop_2(t_gate);      
19
        ZEROCROSS_ON;
20
        _delay_loop_2(20*CNT_1_US);
21
        GATE_OFF
22
        _delay_loop_2(t_high);
23
      }

Das AVR-Studio 4.18 mit avr gcc 2010???? gibt die Warnung

"warning: integer overflow in expression"

aus.

Das bezieht sich auf die Zeile(n)

t_low = CNT_HALF_PERIOD - 2*t_gate;

Warum? Wenn man die Zahlen durchrechnet, kommt 4000-2*t_gate raus, das 
ist doch perfekt. Nur wenn man für CNT_HALF_PERIOD die einfache Zahl 
4000 ins #define reinschreibt, kommt keine Warnung und das Programm 
läuft korrekt. Erklärungen? Berechnet der Compiler den konstanten 
Ausdruck nicht zur Compilezeit? Auch wenn man alle Konstanten mit der 
Endung L versieht, geht es nicht. Ideen?

von Peter II (Gast)


Lesenswert?

Falk B. schrieb:
1
#define F_CPU 8000000L
2
#define T_HALF_PERIOD3       2000   // us -> 4000us period = 250 Hz
3
> T_HALF_PERIOD3 * F_CPU

8000000L * 2000
ist wohl etwas mehr las Long

von Falk B. (falk)


Lesenswert?

Ahhhh, hab ich auch gerade gemerkt!!!!
Kopfrechnen mal wieder schwach!
Trotzdem Danke!

Eine LL Endung wirkt Wunder.

F_CPU 8000000LL

von Ordner (Gast)


Lesenswert?

Falk B. schrieb:
> Berechnet der Compiler den konstanten
> Ausdruck nicht zur Compilezeit?

und wenn bei dieser Berechnung der Overflow auftritt? Bereichsgrenzen 
wird es doch auch bei den Berechnungen zum compilerzeitpunkt geben?!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Falk B. schrieb:
> Eine LL Endung wirkt Wunder.

Es hätte auch genügt, den zweiten Operanden zu klammern:
1
#define CNT_HALF_PERIOD    (T_HALF_PERIOD3 * (F_CPU / 4 / 1000000))

Dann hast du auf der rechten Seite der Multiplikation nur noch eine 2
stehen, und die lässt sich problemlos innerhalb eines 16-bit-Integers
mit 2000 multiplizieren.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falk B. schrieb:
> Berechnet der Compiler den konstanten Ausdruck nicht zur Compilezeit?

Doch, aber dadurch verändert sich nicht die Semantik :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.