Hallo!
Ich versuche gerade, einen bereits hier im Forum geposteten Code einer
Atmel-Appnote (Schrittmotor- Ansteuerung) mit Atmel Studio 6.2 auf einem
Atmega1284 zum Laufen zu bringen.
Darunter findet sich die (hier gekürzte) bedingte Kompilieranweisung
1
#ifdef __GNUC__
2
#include<avr/io.h>
3
#else
4
#include<ioavr.h>
5
#endif
Das _GNUC_ ist nicht farblich hinterlegt, weshalb es wohl nicht
definiert ist. Also definiere ich es artig mit
1
#define __GNUC__
Nun meckert er, es sei redefiniert.
An anderer Stelle meckert er zusätzlich noch,
#if (_GNUC_ == 4 && _GNUC_MINOR_ >= 1) || (_GNUC_ > 4)
operator == has no left operand. Klingt logisch, wenn _GNUC_ als "NIX"
definiert ist.
Also Frage: wo wird dieses _GNUC_ definiert und als was?
Ich hab ja so das Gefüühl dass das mit der toolchain zusammenhängt...
Danke & schönen Gruß
Stephan
Stephan R schrieb:> Das _GNUC_ ist nicht farblich hinterlegt, weshalb es wohl nicht> definiert ist.
Du verwechselstr gerade Compiler und IDE.
Was deine IDE farblich hinterlegt oder nicht hinterlegt, oder welche
Bugs sie hat um welche Präprozessor_makros in welchen Files zu finden
bzw. wie sie mit Makros umgeht, die vom Compiler selbst zur Verfügung
gestellt werden, interessiert den Compiler nicht die Bohne.
Ein Compiler schnappt sich den Quelltext und übersetzt den. Wo dieser
Quelltext herkommt, mit welchem Editor du den erstellt hast und welche
Hilfen wie zb. Farbmarkierungen dieser Editor dem Programmierer zur
Verfügung stellt, interessiert den COmpiler einen feuchten Kehrricht.
Und übrigens: Der Compiler hat immer recht.
> Ich hab ja so das Gefüühl dass das mit der toolchain zusammenhängt...
Ich habe eher das Gefühl, dass der Code, den du kopiert hast ein
Sammelsurium ist, welches sowohl durch den GCC als auch durch einen
anderen Compiler (wie zb. den IAR Compiler) gehen soll.
Wenn dich also der IAR, bzw. andere Compiler nicht wirklich
interessieren, dann wirf einfach alles raus, was von diesem Makro
abhängt und nichts mit dem GCC zu tun hat. Denn um mehr geht es bei
diesem #define nicht.
Stephan R schrieb:> Das GNUC ist nicht farblich hinterlegt,
Das ist ein Problem des Editors. Was der Compiler zu sehen bekommt, ist
eventuell was anderes.
Es gibt eine ganz einfache Grundregel: Allen Namen, die so aussehen
_xxx_, sind Interna des Compilers bzw. der toolchain. Die darfst du
als Programmierer zwar lesend benutzten, aber niemals verändern.
Einfach kompilieren, und gut ist.
Nähre Infos über diese defines finden sich in der gcc-Doku.
Oliver
Stephan R schrieb:> Das GNUC ist nicht farblich hinterlegt, weshalb es wohl nicht> definiert ist.
nein, davon kannst du nicht ausgehen. Das Studio denkt eventuell das es
nicht definiert ist - aber es kann immer noch im Makefile stehen.
> Also definiere ich es artig mit
ist ja noch schlimmer. So etwas schreibt man an eine globale stelle und
nicht in den Quellcode (makefile oder Projekt Einstellungen)
Aber bei GNUC würde ich einfach mal davon ausgehen, das es fest im
Compiler hinterlegt ist. Es wird es nirgends sichtbar definiert sein.
Der if Ausdruck zeigt, dass GNUC einen numerischen Wert haben muss.
Ich vermute mal, dass es die Versionsnummer des GNU C Compilers ist.
Es sollte nicht nötig sein, diese Wertde "manuell" zu definieren. Der
GNU C Compiler setzt sie. Und wenn sie nicht gesetzt sind, dann ist es
kein GNU C Compiler. Auch dafür scheint der Programmcode vorbereitet zu
sein.
http://openbook.galileocomputing.de/c_von_a_bis_z/010_c_praeprozessor_003.htm
Festzustellen, ob eine Definition vorgenommen wurde oder nicht ist ja
wohl eine der leichtesten Übungen.
Die meisten Compiler haben eine Textausgabefunktion wie z.B. #message
oder #error.
Also einfach vorübergehend:
#ifdef _GNUC_
#message ist definiert
#else
#message ist nicht definiert
#endif
einfügen.
Notfalls geht auch:
#ifdef _GNUC_
ist definiert
#else
ist nicht definiert
#endif
letztere Version sollte natürlich einen "echten" Fehler (macht ja nix)
produzieren, aus dem man ersehen kann, was Sache ist.
Stephan R schrieb:> Bei> [...]> meckert der> allwissende Compiler, bei>>
1
>#ifdef__GNUC__
2
>#else
3
>#indlude"verarscht.h"
4
^
5
Huch
6
7
>#endif
8
>
>> nicht.
^^^^^
Müsste er aber. Auch der GNU-C-Compiler kennt kein #indlude.
> Spricht dafür, dass _GNUC_ irgendwo defindiert ist.
Ja, das steckt fest im Compiler.
Oliver S. schrieb:
(Makros, die mit einem Unterstrich beginnen.)
> Die darfst du als Programmierer zwar lesend benutzten, aber niemals> verändern.
Nicht ganz. Man darf sie nur entsprechend der Gebrauchsanleitung
des Compilers bzw. der Systembibliothek benutzen. Falls diese
Anleitung irgendwo schreibt, dass man zum Erreichen eines bestimmten
Verhaltens einen derartigen Makro definieren soll, dann darf man es
natürlich — aber eben nur dann.
Oliver S. schrieb:>> Es gibt eine ganz einfache Grundregel: Allen Namen, die so aussehen> __xxx__, sind Interna des Compilers bzw. der toolchain.
Nicht ganz, es sind alle Namen, die mit
- Zwei _ beginnen
- Einem _ und einem Großbuchstaben beginnen
M.W. wird __GNUC__ auch von clang definiert, was nicht so fein ist und
Probleme bereitet, wenn man clang von GCC unterscheiden will. Für AVR
dürfte das aber kaum eine Rolle spielen.
Übrigens wird __GNUC__ etc. vom GCC nicht nur vom C-Präprozessor
gesetzt, sondern auch von Präprozessoren anderer C-ähnlicher Sprachen
wie GNU-C, C++ oder Objective-C.
Hat man einen GCC X.Y.Z, dann setzt er u.a. folgende Builtin-Makros:
Jörg Wunsch schrieb:> Man darf sie nur entsprechend der Gebrauchsanleitung> des Compilers bzw. der Systembibliothek benutzen.
Tja, das hatte ich tatsächlich auch schon geschrieben, aber dann doch
wieder gelöscht. Anleitungen zu lesen scheint so oldschool zu sein, da
wollte ich den TO nicht zu sehr verwirren.
Oliver
Amateur schrieb:> Die meisten Compiler haben eine Textausgabefunktion wie z.B. #message> oder #error.
Oder, falls der Compiler mit #message nichts anzufangen weiss:
#warning oder #pragma message benutzen