Hallo, ich schreibe grad für den AVR328 ein Programm und trotz guter C Kenntnisse bin ich etwas verwirrt, was die Fähigkeit des GCC angeht zu erkennen, wie lang Zahlen sind. Der AVR ist 8 Bit, ich benutze uint8_t bis uint32_t Formate. Millies ist wohl ein uint32_t. Für einen Timeout möchte ich so verfahren: if (millis() > (to_timer + GSM_ONLINE_PERIOD)) {.....} GSM_ONLINE_PERIOD sollen 90s, also 90.000 ms sein. #define GSM_ONLINE_PERIOD (90*1000) Muss dann hinter das 1000 dieses UL hinter? Steht wohl für unsigned long. Ist beim AVR dann auch 32 Bit. Also #define GSM_ONLINE_PERIOD (90*1000UL) Oder ist der GCC ist der Lage selbst zu erkennen in welches Format die defines passen? Oder wäre es besser zu casten mit (uint32_t)(GSM_ONLINE_PERIOD ) Gruss, Thorsten
Thorsten R. schrieb: > Oder ist der GCC ist der Lage selbst zu erkennen > in welches Format die defines passen? Die #defines sind pure Textersetzung vom Präprozessor, da gibt es keine Zahlen und Wertebereiche. Und für den Compiler ist alles "int" (was auf dem AVR nur 16 Bit breit ist), d.h. wann immer du aus "int" rausläufst, musst du einen größeren Datentyp erzwingen. (long)(großer_ausdruck) läuft trotzdem über, weil (großer_ausdruck) überläuft. Da hilft dann auch eine nachträgliche Erweiterung nicht mehr. Deswegen arbeitet man mit 1000UL.
Übrigens sind das keine Prefixe, sondern Suffixe. Ein Prefix kommt davor, ein Suffix danach.
Hallo, danke für Eure Antworten. Es wird klarer ;-) Gruss, Thorsten
Thorsten R. schrieb: > #define GSM_ONLINE_PERIOD (90*1000UL) > > Oder ist der GCC ist der Lage selbst zu erkennen in welches Format die > defines passen? In C gilt: Der Datentyp, mit dem eine Rechenoperation durchgeführt wird, hängt immer ausschließlich vom Typ der Operanden ab und nicht davon, wie groß das Ergebnis wäre oder wo es gespeichert wird. Bei der Multiplikation werden beide Operanden mindestens auf int erweitert, oder wenn einer größer ist, auf den größten Typ. Das ist auch unabhängig davon, ob die Berechnung zur Compilezeit oder zur Laufzeit durchgeführt wird. Und dann gilt für die Konstanten: Alles, was in einen int passt, ist vom Typ int, wenn man nicht explizit was anderes vorgibt. Da sowohl 90, als auch 1000 vom Typ int sind, wird die Berechnung auch mit int durchgeführt. Da das Ergebnis auf einem AVR nicht in int passt, kommt dann Blödsinn raus. Der Suffix UL oben sagt, dass die 1000 vom Typ unsigned long sein soll. Das führt dazu, dass die 90 ebenfalls nach unsigned long vergrößert wird und die Berechnung dann damit ausgeführt wird. Das Ergebnis ist dann richtig, weil es in unsigned long (32 Bit) passt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.