Hallo zusammen
in meinem Projekt ist die folgende Situation:
// Globale Struct deklaration
struct TestStruct
{
int Test;
};
// Prototypendeklaration
extern Function1(struct TestStruct*);
void Function1(struct TestStruct *Struct2)
{
[...]
}
// Main funktion
int main()
{
struct TestStruct Struct1;
Function1(&Struct1);
}
Beim compilieren bekomme ich gleich in der 1. Zeile den folgenden
Fehler:
"error: redefinition of 'struct TestStruct'"
Allerdings ist das ganze sonst nirgends mehr definiert ?!?
Woran kann das denn liegen?
Danke für eure Hilfe.
Gruß,
Ludwig
Sorry, war nur ein tipfehler beim schreiben des Beitrags.
der Prototyp lautet natürlich
extern void Function1(struct TestStruct*);
Aber an dem liegts ja nicht
die erste Zeile ist Kommentar, an der kann's ja kaum liegen.
Ansonsten kann ich es kompilieren, also hast du wahrscheinlich
noch irgendwas unterschlagen.
Gibt es einen ganzen Quelltext und komplette Fehlermeldungen?
Am besten auch die Fehlermeldungen zu dem Quelltext?
(Wenn du beim Abtippen Fehler gemacht hast, hast du ja wohl
etwas anderes kompiliert als hier steht?)
Danke für die Antwort.
Ich hab mit sicherheit was anderes kompiliert als da steht, da es sich
dabei nur um eine Auszug handelt.
Hab den Fehler aber gefunden, denn die struct definition stand in einer
Header Datei, die versehentlich 2mal eingebunden war.
-> redefinition.
Also Problem gelöst.
Passt.
Ludwig schrieb:
> Danke für die Antwort.>> Ich hab mit sicherheit was anderes kompiliert als da steht, da es sich> dabei nur um eine Auszug handelt.>> Hab den Fehler aber gefunden, denn die struct definition stand in einer> Header Datei, die versehentlich 2mal eingebunden war.
Dagegen sichert man sich mit einem Include Guard ab
header.h
********
1
#ifndef HEADER_H_INCLUDED
2
#define HEADER_H_INCLUDED
3
4
structTestStruct
5
{
6
intTest;
7
};
8
9
// Prototypendeklaration
10
externFunction1(structTestStruct*);
11
12
#endif
Jetzt kannst du header.h in einer Compilation Unit sooft includieren
(direkt oder indirekt) wie du willst oder wie es sich eben ergibt.
Ich habe ein ähnliches Problem auf ner arm CPU
Ich wollte Zarafa (eine Groupware) übersetzen auf x86 läuft der make
durch auf dem sheevaplug habe ich allerdings folgende error meldung
1
In file included from ../../provider/soap/soapH.h:10,
2
from SOAPUtils.h:39,
3
from SOAPUtils.cpp:42:
4
../../provider/soap/soapStub.h:921: error: redefinition of ‘struct user’
5
/usr/include/sys/user.h:50: error: previous definition of ‘struct user’
6
SOAPUtils.cpp: In function ‘ECRESULT CopyUserDetailsToSoap(unsigned int, objectdetails_t, soap*, user*)’:
7
SOAPUtils.cpp:1913: error: ‘struct user’ has no member named ‘ulUserId’
8
SOAPUtils.cpp:1914: error: ‘struct user’ has no member named ‘lpszUsername’
9
SOAPUtils.cpp:1915: error: ‘struct user’ has no member named ‘ulIsNonActive’
10
SOAPUtils.cpp:1916: error: ‘struct user’ has no member named ‘lpszMailAddress’
11
SOAPUtils.cpp:1917: error: ‘struct user’ has no member named ‘lpszFullName’
12
SOAPUtils.cpp:1918: error: ‘struct user’ has no member named ‘ulIsAdmin’
13
SOAPUtils.cpp:1919: error: ‘struct user’ has no member named ‘lpszPassword’
14
SOAPUtils.cpp: In function ‘ECRESULT CopyUserDetailsFromSoap(user*, objectdetails_t*, soap*)’:
15
SOAPUtils.cpp:1928: error: ‘struct user’ has no member named ‘lpszUsername’
16
SOAPUtils.cpp:1929: error: ‘struct user’ has no member named ‘lpszUsername’
17
SOAPUtils.cpp:1931: error: ‘struct user’ has no member named ‘lpszMailAddress’
18
SOAPUtils.cpp:1932: error: ‘struct user’ has no member named ‘lpszMailAddress’
19
SOAPUtils.cpp:1934: error: ‘struct user’ has no member named ‘ulIsAdmin’
20
SOAPUtils.cpp:1935: error: ‘struct user’ has no member named ‘ulIsAdmin’
21
SOAPUtils.cpp:1937: error: ‘struct user’ has no member named ‘ulIsNonActive’
22
SOAPUtils.cpp:1938: error: ‘struct user’ has no member named ‘ulIsNonActive’
23
SOAPUtils.cpp:1940: error: ‘struct user’ has no member named ‘lpszFullName’
24
SOAPUtils.cpp:1941: error: ‘struct user’ has no member named ‘lpszFullName’
25
SOAPUtils.cpp:1943: error: ‘struct user’ has no member named ‘lpszPassword’
26
SOAPUtils.cpp:1944: error: ‘struct user’ has no member named ‘lpszPassword’
Wenn ich es richtig deute wird die user.h doppelt eingebunden.
Aber wieso klappt es auf nem x86
Meine Erfahrungen mit c++ sind etwas verstaubt. Ich steh etwas auf dem
schlauch Das Desgin ist Little Endian und ich kompiliere direkt auf dem
arm. Also ist es kein Cross-Compile Problem
Ich habe mich mal angemeldet vermute das Problem ist etwas komplex kann
mir jemand erklären wie der inculde-guard funktioniert reicht da ein
einfaches "extern"?
Benjamin schrieb:
> ../../provider/soap/soapStub.h:921: error: redefinition of ‘struct user’> /usr/include/sys/user.h:50: error: previous definition of ‘struct user’> Wenn ich es richtig deute wird die user.h doppelt eingebunden.
Ich würde die Compilerausschrift so deuten, dass sowohl soapStub.h
als auch user.h eine struct user definieren. Sehr wahrscheinlich
definieren beide noch dazu eine komplett verschiedene. Da wird
dir wohl oder übel nicht viel übrig bleiben (sofern du beide
Headerdateien wirklich brauchst), als eine von beiden umzubenennen.
> Ich würde die Compilerausschrift so deuten, dass sowohl soapStub.h> als auch user.h eine struct user definieren. Sehr wahrscheinlich> definieren beide noch dazu eine komplett verschiedene. Da wird> dir wohl oder übel nicht viel übrig bleiben (sofern du beide> Headerdateien wirklich brauchst), als eine von beiden umzubenennen.
Vielen Dank für die Antwort reicht es ein
mv /usr/include/sys/user.h /usr/include/sys/user.h_old zu machen oder
muß ich im Code die User.h auszukommentieren
Das Problem ist die User.h wird irgendwie indirekt eingebunden ein grep
-i auf das Verzeichnis hat mir bis jetzt nicht viel gebracht.
Aber mühsam ernährt sich das Eichhörnchen :-)
Ich bin neu auf dem Gebiet bitte entschuldigt die Frage
Okay ich glaube ich versteh was du meinst muß nur noch die richtigen
Stellen im Code finde da stocher ich momentan noch etwas rum für Tipps
bin ich jederzeit dankbar :-)
> Vielen Dank für die Antwort reicht es ein>> mv /usr/include/sys/user.h /usr/include/sys/user.h_old zu machen oder
Das ist ganz übler Pfusch!
Welchen Teil von Jörgs Antwort
> Ich würde die Compilerausschrift so deuten, dass sowohl> soapStub.h als auch user.h eine struct user definieren.
hast Du jetzt eigentlich nicht verstanden?
Das das nicht umbedingt sauber ist weiß ich :-)
ich finde halt nur die Stelle im c-Code nicht.
ich stocher wiegesagt drin rum aber das wird schon hoffe
Ich suche halt die richtige Stelle im code um den Header umzubenennen
ich hab ein find über die source gemacht und das dann gegrept bis jetzt
habe ich nicht die Stelle gefunden wo User.h eingebunden wird
das ist mein Problem
Benjamin Andreas schrieb:
> Ich suche halt die richtige Stelle im code um den Header umzubenennen> ich hab ein find über die source gemacht und das dann gegrept bis jetzt> habe ich nicht die Stelle gefunden wo User.h eingebunden wird
Dann wuerde ich mal nach user.h suchen statt nach User.h.
> Meine Erfahrungen mit c++ sind etwas verstaubt.
Ist wohl die Untertreibung des Jahrhunderts...
Benjamin Andreas schrieb:
> Das das nicht umbedingt sauber ist weiß ich :-)>> ich finde halt nur die Stelle im c-Code nicht.> ich stocher wiegesagt drin rum aber das wird schon hoffe> Ich suche halt die richtige Stelle im code um den Header umzubenennen> ich hab ein find über die source gemacht und das dann gegrept bis jetzt> habe ich nicht die Stelle gefunden wo User.h eingebunden wird
Das ist letztendlich auch ziemlich egal.
Nimm zb die user.h her
* sieh nach ob du include guards drinnen hast
* benenne die struct um
Wirf den Compiler über alles drüber und wenn du nicht allzuviel Pech
hast kommt der Compiler selber drauf welche Files und welche Funktionen
du an den geänderten struct Namen anpassen musst. Warum? Weil er
plötzlich die Member der ursprünglichen struct im Duplikat nicht mehr
finden wird.
In der Funktion, die der Compiler anmäkelt tauscht du dann ebenfalls den
struct Namen, auf die Funktionsargumente nicht vergessen, die
zugehörigen Protoypen nicht vergessen und auf gehts zur nächsten
Compilerrunde. Das machst du solange, bis wieder alles sauber
compiliert.
Der Compiler führt dich durch die notwendigen Änderungen, wenn du einer
struct einen anderen Namen verpasst.
Du darfst allerdings klarerweise die Compiler-Fehlermeldungen nicht für
bare Münze nehmen. Du weißt ja, dass alle Fehler nur dadurch verursacht
sind, dass die struct jetzt einen anderen Namen hat. Jede einzelne
Fehlermeldung ist daher im Grunde nur der Hinweis: Irgendwo vorher muss
es eine struct Variable geben oder einen Pointer auf eine struct, in der
jetzt der falsche struct Name drinnen steht. Ein bischen mitdenken muss
man also, so ganz automatisch gehts nicht.
Und verlier auch nicht zuviel Zeit mit Folgefehlern. Wenn du deine
Fehlerliste durchgehst, die kann durchaus am Anfang des Prozesses ein
paar Hundert Fehler umfassen, dann arbeite nicht alle Fehler durch. Nimm
dir die ersten paar vor und drück dann auf "compile". Mit jedem 'Fehler'
den du ausbaust, werden auch eine Unmenge an Folgefehler verschwinden
(und manchmal ein paar neue Fehlermeldungen dazukommen)
Für hartnäckige Fälle, bei denen man partout nicht finden kann,
wer denn nun das #include <sys/user.h> dort verbrochen hat, kann
man sich die Ausgaben des Präprozessors ansehen. Dazu benutzt
man die Option -E (statt -c), die Ausgabe landet entweder auf
stdout (kann man nach "more" oder "less" weiterleiten) oder aber
in der per -o benannten Datei.
Darin finden sich dann solche Dinge wieder:
Das bedeutet, dass ab Zeile 43 in Src/Lib/Inc/board.h zwei leere
Zeilen generiert werden (da könnten in der Datei bspw. auch #define
oder #ifdef stehen, denn die werden vom Präprozessor in der Ausgabe
gelöscht), danach wird offenbar <avr/io.h> aufgerufen. In avr/io.h
springt der Präprozessor dann von Zeile 1 auf Zeile 99 (am Anfang
der Datei liegt ein sehr großer Kommentar, den er entfernt hat), und
auf Zeile 99 wird dann <avr/sfr_defs.h> reingezogen.
Wenn man in einer derartigen Ausgabe das erste Vorkommen von
sys/user.h sucht und von dort rückwärts geht, sollte man herausfinden,
welche Stelle in welcher Datei das zugehörige #include enthält.
Karl heinz Buchegger schrieb:
> Das ist letztendlich auch ziemlich egal.> Nimm zb die user.h her
Das ist natürlich Quatsch.
Da die user.h aus dem sys Zweig ist, lässt du die klarerweise in Ruhe.
Du änderst den Namen der struct im anderen Header File.
Das restliche Vorgehen bleibt dasselbe, wobei noch ein Hinweis auf die
Fähigkeiten des Editors erfolgen soll:
Replace im File, wobei sinnigerweise 'whole word only' und 'respect
case' eingeschaltet werden sollte, sofern vorhanden.
Habe die struct umbenannt war eigenlich recht simple nochmal vielen
dank für die super erklärung
hat super geklappt warum der Fehler aufm arm auftritt und auf nem x86
nicht bleibt mir zwar ein Rätsel aber nun habe ich fertige Arm Binarys
P.s das make hat 2 stunden gdauert das nächste mal compiliere ich lieber
cross auf ner CPU mit ordentlich FPU :-)
Nochmal Danke