Hallo Leute,
ich hab mal wieder ein Problem.
Ich habe einen funktionierenden Code dahingehend geändert, Dass ich
Graphik-Funktionen, die bisher in der main.c waren in eine graphics.c
ausgelagert habe, die entsprechenden Funktionen dann in der includierten
graphics.h deklariert. Soweit alles gut.
Dann habe ich das gleiche mit der ( so ziemlich) einzigen adc-Funktion
gemacht. Also Funktion in die adc.c und dann eben in der adc.h
deklariert.
Nun bringt der Compiler den Fehler:
1
adc.c:3:error: expected '=', ',', ';', 'asm' or '__attribute__' before 'ReadChannel'
Wenn man die adc.c weglässt, und alles in die adc.h schreibt
funktioniert es. ( Soll ja aber nicht sein, daß Funktionen in einer *.h
sind...- wie ich ja vergangene Woche erst gelernt hab)
Die adc.h wird in der main.c includiert.
@ Rufus
Das war´s!
In der adc.c wurde gar nix includiert. Habe nun <stdint.h>, <avr/io.h>,
<stdlib.h> includiert. Jetzt baut er es.
Danke für die Antworten !
Hier jetzt mal die kompletten Dateien...
Ich hatte aber die <stdint.h> bzw. <inttypes.h> bisher überhaupt nicht
includiert. Und es hat trotzdem funktioniert.
Du solltest in der adc.c dringend auch adc.h includieren, entsprechend
auch für graphics.*. Dadurch verhinderst du (bzw. der Compiler), dass
sich Header-Datei und Code-Datei versehentlich auseinander entwickeln.
In der graphics.c steht vor den <...>-Includes ein Include mit "...".
Das kann im Einzelfall OK sein, ist aber eher eine mögliche
Fehlerquelle.
Edit: auch in der main.c
@ tobi && @ Konrad
das mit dem Includieren der *.h in den *.c führt leider wieder zum
ursprünglichen Compiler-Fehler.
Ich habe nun die Reihenfolge der Includes geändert..
erst die vom compiler <bla>
dann die eigenen "bla"
Giuseppe B. schrieb:> Ich habe nun die Reihenfolge der Includes geändert..>> erst die vom compiler <bla>> dann die eigenen "bla"
Und dann gehts? Dann fehlt in einem Deiner eigenen Header noch etwas ...
Giuseppe B. schrieb:> das mit dem Includieren der *.h in den *.c führt leider wieder zum> ursprünglichen Compiler-Fehler.
Dann machst Du da noch irgendwas falsch.
Die adc.h muss sich in adc.c einbinden lassen, und zwar als letzte
#include-Datei, nach allen anderen #include-Anweisungen und vor dem in
adc.c enthaltenem Code.
Wenn es da immer noch Fehlermeldungen gibt, poste exakt die
Headerdatei, die C-Datei und die Fehlermeldung(en).
Rufus Τ. Firefly schrieb:> Die adc.h muss sich in adc.c einbinden lassen, und zwar als letzte> #include-Datei, nach allen anderen #include-Anweisungen und vor dem in> adc.c enthaltenem Code.
Wenn man es richtig macht, sollte man sie doch sogar als allererste
einbinden können. Ist der beste Test, um zu sehen, ob noch etwas fehlt.
@ Rufus
Nicht ganz so... es ging nachdem ich die <stdint.h>, <avr/io.h> und
<stdlib.h> in die adc.c includiert hatte.
seit dem Includieren der entsprechenden *.h ind die *.c kommt wieder
folgender Fehler:
1
In file included from graphics.c:37:
2
graphics.h:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'u8g'
3
make: *** [graphics.o] Fehler 1
Diesmal bzgl. der graphics.h .
Dann noch die "u8g.h" in die graphics.h includiert. Jetz geht´s wieder.
Dass man aber *.h in *.h includieren darf stand so nicht im ebook :)
Und noch ne Frage:
Wenn in der Makefile steht...
1
z.B. SRC: = *.c
...
Was baut dann der Compiler zuerst, bzw. macht er die main.c zuerst oder
zuletzt ? Oder macht er es alphabetisch ?
xfr schrieb:> Wenn man es richtig macht, sollte man sie doch sogar als allererste> einbinden können. Ist der beste Test, um zu sehen, ob noch etwas fehlt.
Das sehe ich anders. Da müsste die xxx.h sämtliche Header einbinden, die
auch die xxx.c zum Übersetzen braucht. Das tut evtl. bei einem
AVR-Projekt wegen der überschaubaren Größe nicht weh. Bei einem richtig
großen Projekt wirst du keine Freude daran haben, weil - egal welchen
Header du änderst - du immer das gesamte Projekt neu kompilieren musst.
Rufus Τ. Firefly schrieb:> Giuseppe B. schrieb:>> Dann noch die "u8g.h" in die graphics.h includiert. Jetz geht´s wieder.>> Es mag zwar gehen, ist aber murks.
Exakt. Siehe mein Beitrag von eben.
Giuseppe B. schrieb:> Was baut dann der Compiler zuerst, bzw. macht er die main.c zuerst oder> zuletzt ? Oder macht er es alphabetisch ?
Wahrscheinlich alphabetisch. Spielt aber keine Rolle, da alle c-Dateien
unabhängig voneinander kompiliert werden und erst danach vom Linker zu
einem Programm zusammengesetzt werden.
Man darf übrigens nicht nur h-Dateien in h-Dateien inkluden, es ist
dringend zu empfehlen! Jede Datei sollte in sich vollständig sein. Die
Vorgehensweise ist im Prinzip, jede Datei Zeile für Zeile durchzugehen.
Jedes Wort, das nicht weiter oben in der gleichen Datei deklariert ist
oder zur C-Programmiersprache gehört, kann nur aus einer anderen
inkludierten Datei stammen. Die muss dann eingebunden werden.
Konrad S. schrieb:> Das sehe ich anders. Da müsste die xxx.h sämtliche Header einbinden, die> auch die xxx.c zum Übersetzen braucht. Das tut evtl. bei einem> AVR-Projekt wegen der überschaubaren Größe nicht weh. Bei einem richtig> großen Projekt wirst du keine Freude daran haben, weil - egal welchen> Header du änderst - du immer das gesamte Projekt neu kompilieren musst.
Nein, xxx.h muss nur sämtliche Header einbinden, auf deren Teile
irgendwo in xxx.h verwiesen wird. Alle Header, die in xxx.c gebraucht
werden (aber nicht in xxx.h) bindet man natürlich auch nur in xxx.c ein.
Mal ein Beispiel
du hast einen header Vector.h, in dem z.B. steht
1
typedefstruct
2
{
3
uint8_tx;
4
uint8_ty;
5
uint8_tz;
6
}Vector_t;
In dem struct findest Du den Datentyp uint8_t. Jetzt könnte man noch die
stdint.h vor dem typedef noch im inkludieren, damit der Compiler weiss
was ein uint8_t. Das macht man oder besser gesagt das mache ich nicht.
In meinem vektor.c würde ich erst alles inkludieren was mit spitzen
Klammern zu tun hat, und erst dann meine header.
Warum? Es ist für mich eine reine Deklaration. Ich möchte hier noch
nicht sagen, was ein uint8_t ist. Das ganze wird dann portabler. Zum
Anderen, wenn sich die uint8_t nicht mehr in stdint.h befinden würde,
bräuchtest Du das header file trotzdem nicht anfassen. Ok. das ein
uint8_t sich nicht mehr in stdint.h befindet, mag ein blödes beispiel
sein.
Ich habe zwischenzeitlich ziemlich viele Includes entfernt.
Im Anhang nochmals alle Files im aktuellen Zustand.
Es hat wohl daran gelegen, daß in der graphics.c, welche hauptsächlich
mit der u8glib arbeitet, die "u8g.h" nicht includiert war.
Dass sich das Problem zu Anfangs aud die adc.c ausgewirkt lag wohl an
der fehlenden <io.h> ???
uC Writer schrieb:> Mal ein Beispiel>> du hast einen header Vector.h, in dem z.B. steht> typedef struct> {> uint8_t x;> uint8_t y;> uint8_t z;> } Vector_t;>> In dem struct findest Du den Datentyp uint8_t. Jetzt könnte man noch die> stdint.h vor dem typedef noch im inkludieren, damit der Compiler weiss> was ein uint8_t. Das macht man oder besser gesagt das mache ich nicht.> In meinem vektor.c würde ich erst alles inkludieren was mit spitzen> Klammern zu tun hat, und erst dann meine header.>> Warum? Es ist für mich eine reine Deklaration. Ich möchte hier noch> nicht sagen, was ein uint8_t ist. Das ganze wird dann portabler. Zum> Anderen, wenn sich die uint8_t nicht mehr in stdint.h befinden würde,> bräuchtest Du das header file trotzdem nicht anfassen. Ok. das ein> uint8_t sich nicht mehr in stdint.h befindet, mag ein blödes beispiel> sein.
Und wie siehst Deine vektor.c aus? Dort muss ein konkreter Typ bekannt
sein. Also musst Du dort stdint.h einbinden. Damit ist dann aber auch
festgelegt, was die Implementierung der Funktionen für einen Typ
erwartet, nämlich ein unsigned char.
Wenn jetzt ein Benutzer der Bibliothek auf die Idee kommt, uint8_t vor
dem Einbinden Deiner vektor.h anders zu definieren als in stdint.h,
stimmen Deklaration in vektor.h und Implementierung in vektor.c nicht
mehr überein und es kracht.
Wenn die Implementierung (vektor.c) mit anderen Datentypen umgehen soll,
dann muss in vektor.c ein entsprechender Header (z.B. vektor_type.h)
eingebunden sein. Es reicht nicht, dass der Benutzer das in seinem
Programm macht! Und damit wären wieder beim Anfang: Dieser Header wird
sowohl in vektor.c als auch im Programm des Benutzers gebraucht und muss
gleich sein, also packt man ihn sinnigerweise gleich in vektor.h.
xfr schrieb:> Giuseppe B. schrieb:>> Was baut dann der Compiler zuerst, bzw. macht er die main.c zuerst oder>> zuletzt ? Oder macht er es alphabetisch ?>> Wahrscheinlich alphabetisch. Spielt aber keine Rolle, da alle c-Dateien> unabhängig voneinander kompiliert werden und erst danach vom Linker zu> einem Programm zusammengesetzt werden.
Die Reihenfolge wird durch die im Makefile formulierten Abhängigkeiten
festgelegt.
@xfr
Deine Argumentation bezüglich Includes ist schon richtig. Aber meine
Erfahrung bei großen Projekten brachte mich zur Ansicht, dass es eine
gute Idee ist, wenn ein Header nur das Interface verkauft, für das er
selbst zuständig ist. Daher findet sich in meinen Headern dann sowas:
1
structbinwoanderszuhause;
2
intfunktionsowieso(binwoanderszuhause*x);
Den Header mit den Details zu struct binwoanderszuhause ziehen sich nur
die Code-Dateien rein, die es nötig haben.
@xfr
Wenn der Benutzer auf die Idee käme uint8_t selber zu deklarieren? Na
dann hat derjenge noch ein paar andere Leichen im Keller.
Und wenn man uint8_t selber deklariert und danach die stdint inkludiert,
in der dann uint8_t nochmals deklariert wird, sollte es ein
Compiler-Fehler geben. Zumindest habe ich das noch nicht geschafft.
Vielleicht ein Beispiel?
Und es sollte natürlich klar sein, dass ich in meiner vektor.c die
stdint.h inkludiere. Zumindest bei mir geht das mit
1
#include<stdint.h>
also die Files mit den spitzen Klammern.
Mach es aber wie Du magst.
Konrad S. schrieb:> @xfr> Deine Argumentation bezüglich Includes ist schon richtig. Aber meine> Erfahrung bei großen Projekten brachte mich zur Ansicht, dass es eine> gute Idee ist, wenn ein Header nur das Interface verkauft, für das er> selbst zuständig ist. Daher findet sich in meinen Headern dann sowas:>> struct binwoanderszuhause;> int funktionsowieso( binwoanderszuhause *x );>> Den Header mit den Details zu struct binwoanderszuhause ziehen sich nur> die Code-Dateien rein, die es nötig haben.
In dem Fall kann man sich drüber streiten. Wenn jemand funktionsowieso()
verwenden will, braucht er die Definition von struct binwoanderszuhause.
Also kann man sie ihm auch gleich mitgeben. Es ist ja (wie oben
beschrieben) nicht möglich, dass sich der Benutzer aussucht, wie struct
binwoanderszuhause auszusehen hat, sondern er muss genau die Version
nehmen, die auch der Implementierung von funktionsowieso() zu Grunde
liegt.
In Deinem Beispiel kompiliert das Programm aber immerhin, da struct
binwoanderszuhause ja zumindest deklariert wurde. In dem Beispiel mit
uint8_t gibt es dagegen Compilerfehler.
uC Writer schrieb:> Wenn der Benutzer auf die Idee käme uint8_t selber zu deklarieren? Na> dann hat derjenge noch ein paar andere Leichen im Keller.
Genau das wolltest Du doch aber erreichen:
> Warum? Es ist für mich eine reine Deklaration. Ich möchte hier noch> nicht sagen, was ein uint8_t ist.
Wenn Du nicht sagst, was ein uint8_t ist und der Benutzer es auch nicht
sagen soll, wer bleibt denn dann noch?
> Und wenn man uint8_t selber deklariert und danach die stdint inkludiert,> in der dann uint8_t nochmals deklariert wird, sollte es ein> Compiler-Fehler geben. Zumindest habe ich das noch nicht geschafft.> Vielleicht ein Beispiel?
Genau. Dadurch dass man stdint.h in vektor.h inkludiert, gibt es einen
Fehler, wenn der Benutzer versuchen würde, uint8_t anders zu
deklarieren. Wenn in vektor.h dagegen nichts von stdint.h steht, hält
den Benutzer niemand davon ab. Und genau das ist gefährlich.
> Und es sollte natürlich klar sein, dass ich in meiner vektor.c die> stdint.h inkludiere. Zumindest bei mir geht das mit#include <stdint.h>> also die Files mit den spitzen Klammern.> Mach es aber wie Du magst.
Damit ist dann Dein zweites Argument auch keins:
> Zum Anderen, wenn sich die uint8_t nicht mehr in stdint.h befinden würde,> bräuchtest Du das header file trotzdem nicht anfassen. Ok. das ein> uint8_t sich nicht mehr in stdint.h befindet, mag ein blödes beispiel> sein.
Denn wenn sich uint8_t nicht mehr in stdint.h befinden würde, müsstest
Du Deine vektor.c anfassen. Und nicht nur die, sondern auch alle
Programme, die Deine Header-Datei mit uint8_t ohne Einbinden von
stdint.h verwenden. Wenn Du es dagegen in vektor.h hättest, bräuchst Du
es nur an dieser einen Stelle ändern.
xfr schrieb:> Wenn jemand funktionsowieso()> verwenden will, braucht er die Definition von struct binwoanderszuhause.
Nicht unbedingt. Beispiel: FILE *
Wenn du dir z.B. Microsofts Umgang mit FILE-Pointern anschaust, dann
hast du ein Beispiel, dass es auch möglich ist, in unterschiedlichen
Kontexten (z.B. DLLs) mit unterschiedlichen Implementierungen der struct
FILE zu arbeiten. Du darfst diesen FILE-Pointer zwar in andere Kontexte
weiterreichen, musst aber sicherstellen, dass er nur in "geeigneten"
Kontexten verwendet wird. So können unterschiedliche
FILE-Implementierungen innerhalb einer Applikation koexistieren, ohne
einen Crash zu verursachen. OK, klar ist das irgendwo zwischen "nicht
unbedingt empfehlenswert" und "absoluter Schwachsinn" anzusiedeln, aber
so kann Uralt-Software auf neueren Systemen weiterverwendet werden.
Ich verwende diese Technik des "nur das Interface beschreiben" gerne für
eigenständige Subsysteme. Der Nutzer eines solchen Subsystems ist
vollständig unabhängig von der Implementierung des Subsystems. Solange
sich das vom Nutzer verwendete Interface nicht ändert - es kann aber
erweitert werden - muss er bei einer neuen Implementierung des
Subsystems seinen Quellcode nicht neu übersetzen. Das Subsystem ist
somit einfach austauschbar. Eber das Prinzip der DLL bzw. Shared
Objects.
Mit Microsofts FILE-Pointer kenne ich mich leider nicht aus. Kannst Du
es kurz erklären? Gibt es da quasi eine file_old.h und file_new.h und
manche DLLs wollen ein FILE gemäß file_old.h und manche nach file_new.h?
Und ich als Anwender muss die richtige file_*.h einbinden, je nachdem
mit welcher DLL ich rede? Das wäre imo gerade ein Anti-Beispiel. Kann
mir gerade nicht vorstellen, wie man innerhalb einer c-Datei
verschiedene Varianten von FILE-Pointern nebeneinander verwenden kann.
xfr schrieb:> Mit Microsofts FILE-Pointer kenne ich mich leider nicht aus.
Du Glücklicher!
Aber immerhin bezahlen sie mich dafür - Schmerzensgeld also. ;-)
> Kannst Du> es kurz erklären? Gibt es da quasi eine file_old.h und file_new.h und> manche DLLs wollen ein FILE gemäß file_old.h und manche nach file_new.h?> Und ich als Anwender muss die richtige file_*.h einbinden, je nachdem> mit welcher DLL ich rede?
Nein, du inkludierst immer nur stdio.h. Du wählst nur die
Compileroptionen, die dir am wenigsten grausam vorkommen. Das hat dann
Einfluss auf Speichermodell, Aufrufkonventionen und die Schuhgröße des
Anwenders, bei dem die Applikation nicht crasht.
> Kann> mir gerade nicht vorstellen, wie man innerhalb einer c-Datei> verschiedene Varianten von FILE-Pointern nebeneinander verwenden kann.
Nicht innerhalb einer C-Datei, nur innerhalb einer Applikation. Z.B.
kann die x.exe mit einer anderen Vorstellung von FILE kompiliert sein
als die y.dll, die von der x.exe eingebunden wird. Wenn y.dll einen
FILE-Pointer an die x.exe herausrückt und x.exe damit arbeitet, dann
crasht es eben. x.exe kann mit diesem FILE-Pointer aber problemlos eine
Funktion von y.dll aufrufen, die mit dem FILE-Pointer arbeitet. Das
funktioniert deshalb, weil jede DLL und EXE gegen eine bestimmte libc
(bzw. msvcrtschlagmichtot.xyz) gelinkt ist - wobei "funktionieren" hier
großzügig ausgelegt werden muss.
Konrad S. schrieb:> Nicht innerhalb einer C-Datei, nur innerhalb einer Applikation. Z.B.> kann die x.exe mit einer anderen Vorstellung von FILE kompiliert sein> als die y.dll, die von der x.exe eingebunden wird. Wenn y.dll einen> FILE-Pointer an die x.exe herausrückt und x.exe damit arbeitet, dann> crasht es eben. x.exe kann mit diesem FILE-Pointer aber problemlos eine> Funktion von y.dll aufrufen, die mit dem FILE-Pointer arbeitet. Das> funktioniert deshalb, weil jede DLL und EXE gegen eine bestimmte libc> (bzw. msvcrtschlagmichtot.xyz) gelinkt ist - wobei "funktionieren" hier> großzügig ausgelegt werden muss.
Okay, glaube das habe ich einigermaßen verstanden. Man bindet also in
x.exe eigentlich ein andere Definition von FILE ein, als y.dll verwendet
hat. Da ein Pointer aber immer gleich groß ist, kann man einen
FILE-Pointer, den man von y.dll bekommen hat bei sich speichern und
wieder an y.dll zurückgeben. Erst wenn man FILE derefenzieren und an den
Daten etwas ändern würde, käme Schrott bei raus?
Das würde aber doch auch noch "funktionieren", wenn in y.h stdio.h
eingebunden wäre, oder? Es wäre dann zwar die falsche Version (für
y.dll), aber wenn man nur x.exe kompiliert und nicht y.dll (was wegen
der falschen Definition eh scheitern dürfte), hat man das gleiche
Ergebnis. Welche Definition von FILE für das aktuelle Programm verwendet
wird, legt man ja anscheinend durch die Compilereinstellungen fest und
nicht durch den Namen der h-Datei.
Davon abgesehen würde ich so ein System absolut nicht als Vorbild für
den Entwurf von neuer Software sehen ... ;-)
xfr schrieb:> Erst wenn man FILE derefenzieren und an den> Daten etwas ändern würde, käme Schrott bei raus?
Ganz genau! Solange man den FILE-Pointer nur als Magic Cookie (ahem -
"Handle") weiterreicht, ist die Welt in Ordnung.
> Das würde aber doch auch noch "funktionieren", wenn in y.h stdio.h> eingebunden wäre, oder? Es wäre dann zwar die falsche Version (für> y.dll), aber wenn man nur x.exe kompiliert und nicht y.dll (was wegen> der falschen Definition eh scheitern dürfte), hat man das gleiche> Ergebnis. Welche Definition von FILE für das aktuelle Programm verwendet> wird, legt man ja anscheinend durch die Compilereinstellungen fest und> nicht durch den Namen der h-Datei.
Sofern die Details der struct FILE in stdio.h enthalten sein sollten -
wozu? - müsste sie sich eben durch die Copileroptionen Makro-gesteuert
anpassen.
> Davon abgesehen würde ich so ein System absolut nicht als Vorbild für> den Entwurf von neuer Software sehen ... ;-)
Als aufwendiges Beispiel für "Wie schieße ich mir ohne Colt in den Fuß?"
taugt es allemal. ;-)
Es ging ja ursprünglich darum, ob man in seinen Headerdateien die
anderen Headerdateien, auf die sich das Interface bezieht, mit einbinden
soll oder nicht. Weiter oben habe ich ein paar Gründe genannt, die dafür
sprechen und bisher keinen gelesen, der dagegen spricht.
Also ob ich als Entwickler von meinmodul.c folgenden Header schreiben
soll:
1
// meinmodul.h
2
3
voidtu_was(uint16_tbla);
4
voidlese_datei(FILE*file);
Dann muss mein Hauptprogramm zwingend so aussehen:
1
// main.c
2
3
#include<stdint.h>
4
#include<stdio.h>
5
#include"meinmodul.h"
Es muss es in der Reihenfolge da stehen und ich muss stdint.h und
stdio.h einbinden, obwohl ich selber vielleicht gar nichts daraus nutze.
Außerdem muss ich wissen, dass uint16_t aus stdint.h kommt und FILE aus
stdio.h. Gut, hier kann man das voraussetzen, wenn es aber keine
Standard-Header sind nicht.
Die aus meiner Sicht immer bessere Variante ist dagegen:
1
// meinmodul.h
2
3
#include<stdint.h>
4
#include<stdio.h>
5
6
voidtu_was(uint16_tbla);
7
voidlese_datei(FILE*file);
Dann reicht im Hauptprogramm:
1
// main.c
2
3
#include"meinmodul.h"
Ebenso funktioniert:
1
// main.c
2
3
#include"meinmodul.h"
4
#include<stdint.h>
Oder natürlich auch die Variante von oben. Nur wenn ich im Hauptprogramm
falsche Headerdateien einbinde, die eine andere Definition mit gleichem
Namen enthalten oder Dinge neu definiere, die im Interface benutzt
werden, bekomme ich zu Recht einen Compilerfehler.
Gegen das Einbinden von "<...>"-Headern (also "System"-Header) in
eigenen h-Dateien spricht mMn nichts, da man diese Sorte Header als
statisch ansehen darf und diese Header immer (hoffentlich?!?) gegen
unerwünschte Nebenwirkungen durch mehrfaches Inkludieren abgesichert
sind. Den Fall von Kernel-naher Entwicklung unter Linux mit
dazwischenliegendem Kernel-Update lasse ich mal außer Acht.
Wenn die '"..."'-Header ordentlich gemacht sind - Absicherung gegen
mehrfaches Inkludieren - spricht technisch gesehen auch nichts dagegen.
Ich versuche allerdings, dass ich eben gerade keine dieser Header in
die h-Datei aufnehmen muss; ich vermeide es, wenn es mit sinnvollem
Aufwand machbar ist. Ich will in die c-Datei nur das allernötigste
reinziehen und ich will keine unnötigen Abhängigkeiten schaffen. Ich bin
also kein Anhänger der "global.h"-Technik, bei der man das gesamte
Projekt neu kompiliert, nur weil sich in einem einzigen Header eine
Kleinigkeit geändert hat. Aber es ist eine Frage des Geschmacks, über
die sich streiten lässt - richtig und falsch sind hier einfach
unpassende Attribute.
So etwas hingegen
1
#include"meinmodul.h"
2
#include<stdint.h>
halte ich für gefährlich. Je nach Mitteilsamkeit des Compilers kann die
Fehlersuche ausarten. Als problematisch sehe ich hier die Verstöße gegen
reservierte Namen(sbereiche) an.