Hallo
Der folgende Code wird so ähnlich in einem Programm für einen ARM
benutzt. Compiliert wird der Code mit Keil, und dieser hat keine Fehler.
Für automatisierte Test's wird der selbe Code nun mit einem GCC
compiliert, um in CUTE dann die Teste auszuführen.
Der GCC hat aber mit dem Vergeleich der beiden Pointer ein Problem und
endet mit der Fehlermeldung "Could not find operator>= for type bool".
Hier soll aber nicht Verglichen werden ob Klasse pWritePosition >=
Klasse pEndPosition ist, sondern ob die Speicherposition pWritePosition
die Speicherposition pEndPosition überschritten hat.
Wie bekomme ich den GCC dazu dies zu machen? Gibt es eine
Compileroption? Eine Codeänderung möchte ich nicht machen, da der
Keilcompiler ja kein Problem hat.
Danke schon ma im Vorraus.
1
#pragma pack(1)
2
typedefstruct/**< Struktur eines TLV Kopfes ( T & L & 1.V) */
entspricht deiner ersten Variante, ist mir bei der Abänderung des Codes
für das Forum ein kleiner Fehler unterlaufen. Die beiden Variablen sind
eigentlich private Variablen der Klasse in der der Code ausgeführt wird.
Ändert aber an der Fehlermeldung nichts.
Wenn ich einen der beiden Pointer auf void caste, dann läuft es.
In etwa so:
1
voidfoo(void)
2
{
3
TLVHead_Def*pWritePosition;
4
TLVHead_Def*pEndPosition;
5
6
if((void*)pWritePosition>=pEndPosition)
7
{
8
machwas;
9
}
10
}
Aber wie gesagt, möchte ich nichts am Code ändern.
Gruß Steffen
Ich bin mir zwar nicht sicher, aber es kann durchaus sein das das
überhaupt nicht zulässig ist.
Es macht ja auch überhaupt keinen Sinn pointer auf größer zu
vergleichen. Nur weil wir es uns immer als Adresse vorstellen muss es
noch lange keine wirkiche zahl sein.
Auf == prüfen ist klar definiert. Aber größer oder kleiner? Wozu
brauchst du soetwas denn?
(Mich wird bestimmt gleiche jemand korrigieren wenn es falsch ist)
Steffen Graap schrieb:> Alaso ich meine es so:
Dann schreibs auch so, wie du es meinst.
Wenn du dir nicht sicher bist, was du tust, dann schreib pro
Variablendefinition nur EINE Variable.
> TLVHead_Def* pWritePosition;> TLVHead_Def* pEndPosition;
Ganz genau so.
> Ändert aber an der Fehlermeldung nichts.
Dann zeig deinen richtigen Code.
Denn das diese Fehlermeldung mit dem gezeigten Code nichts zu tun hat,
zeigt sich schon darin, dass der Compiler einen Datentyp 'bool'
anspricht, in deinem Codefetzen aber weit und breit von einem bool
nichts zu sehen ist.
> Wenn ich einen der beiden Pointer auf void caste, dann läuft es.
und ist ziemlich sicher falsch.
Mit einem derartigen Cast sagst du dem Compiler hauptsächlich eines:
Halt die Klappe!
Peter II schrieb:> Es macht ja auch überhaupt keinen Sinn pointer auf größer zu> vergleichen. Nur weil wir es uns immer als Adresse vorstellen muss es> noch lange keine wirkiche zahl sein.
Doch, das ist so definiert, dass es auch auf Pointer eine größer/kleiner
Relation gibt.
Was nicht definiert ist ist, das man einfach beliebige Pointer nehmen
kann.
Aber solange die Pointer in das gleiche Array zeigen, muss es eine
größer/kleiner Relation geben.
Wobei: genau genommen ist IMHO noch nicht mal von Arrays die Rede,
sondern von Datenobjekten, wobei man mich jetzt bitte nicht auf den
genauen Wortlaut festnageln möge. D.h. auch in einer Struktur gilt für
die Strukturmember eine größer/kleiner Beziehung in Adress- und damit
Pointerdingen.
Peter II schrieb:> Wozu> brauchst du soetwas denn?
Erlaubt ist es. Ob es sinnvoll eingesetzt wird, kommt auf den
Programmierer an.
Es macht z.B. dann Sinn, in einem Array zu prüfen, ob man die Grenzen
erreicht hat.
Einfach zwei Pointer zu vergleichen, ohne dass sie einen Bezug
zueinander haben, ist natürlich fatal.
VG
Thomas
Das ganze Konstrukt dient um einen Speicher, in dem eine TLV-Nachricht
(Tag, Length, Value) liegt zu durchsuchen und
auseinanderzunehmen/zusammenszustellen. In diesem Fall sind die Pointer
Zeiger in einen Speicher, und dem zufolge sollten sie auch vergeleichbar
sein.
Ursprünglich waren die Pointer vom Typ "unsigned char* ".
Zur besseren Verarbeitung wurde die Struktur eingefügt, um so einfacher
und definierter auf Tag, Länge und den Wert drauf zuzugreifen. Sieht
einfach besser aus wenn man mit pWritePosition->startValue als mit
*(pWritePosition + 4) arbeitet.
Gruß Steffen
Steffen Graap schrieb:> und definierter auf Tag, Länge und den Wert drauf zuzugreifen. Sieht> einfach besser aus wenn man mit pWritePosition->startValue als mit> *(pWritePosition + 4) arbeitet.
Alles schön und gut.
Trotzdem ist in
1
voidfoo(void)
2
{
3
TLVHead_Def*pWritePosition;
4
TLVHead_Def*pEndPosition;
5
6
if(pWritePosition>=pEndPosition)
7
{
8
machwas;
9
}
10
}
abgesehen davon, dass die Pointer uninitialisiert sind, erst mal nichts
falsch.
Wenn du also noch immer eine Fehlermeldung kriegst, dann hat die nichts
mehr mit dem Vergleich zu tun, sondern damit, dass du irgendwo anders
noch eine Verschlimmbesserung eingebaut hast.
Karl Heinz Buchegger schrieb:> Denn das diese Fehlermeldung mit dem gezeigten Code nichts zu tun hat,> zeigt sich schon darin, dass der Compiler einen Datentyp 'bool'> anspricht, in deinem Codefetzen aber weit und breit von einem bool> nichts zu sehen ist.
genau das ist ja das Problem, es gibt hier kein bool.
hier noch mal der ungefilterte Code, einer Fehlermeldung. In anderen
Methoden tritt der Fehler auch auf. Der a b Vergleich dient zum Test,
der Vergleich ein stückchen tiefer mit den beiden void casts war der
ursprüngliche der jetzt so läuft.
Kann es sein, dass du nicht den C, sondern den C++-Compiler benutzt?
In C++ ist das so nicht erlaubt.
Da muss deiner Klasse (Struktur) der => Operator hinzugefügt werden!
Das würde erklären, warum er den "operator =>" anmeckert. Der Operator
=> gibt namlich einen bool zurück.
Steht da noch ne Fehlernummer vor dem Fehlertext?
VG
Thomas
Thomas Weyhrauch schrieb:> Kann es sein, dass du nicht den C, sondern den C++-Compiler benutzt?>> In C++ ist das so nicht erlaubt.> Da muss deiner Klasse (Struktur) der => Operator hinzugefügt werden!>> Das würde erklären, warum er den "operator =>" anmeckert. Der Operator> => gibt namlich einen bool zurück.>> Steht da noch ne Fehlernummer vor dem Fehlertext?
Ja es is C++
Der Keil-Compiler compiliert den Code Fehlerfrei und er läuft auch schon
seit einem halben Jahr richtig auf der Hardware.
Fehlernummer sehe ich keine.
Steffen
Thomas Weyhrauch schrieb:> Kann es sein, dass du nicht den C, sondern den C++-Compiler benutzt?>> In C++ ist das so nicht erlaubt.> Da muss deiner Klasse (Struktur) der => Operator hinzugefügt werden!>> Das würde erklären, warum er den "operator =>" anmeckert. Der Operator> => gibt namlich einen bool zurück.
Vergiss den Beitrag. Da bin ich eben falsch abgebogen. Klar geht das
auch in C++ kopfschüttel
TLVHead_Def*_pWritePosition;//!< Positionen andem ein neuer Tag geschrieben wird. Momentan nur Anhängen möglich!
2
....
3
4
TLVHead_Def*_pEndPosition[HIERARCHIE_DEEP];//!< Positionen hinter dem letzten Tag der Hierarchieebene im Speicher
5
6
....
7
8
if(pWritePosition>=pEndPosition)
Das eine ist ein Array von Pointern, das andere ist ein einzelner
Pointer.
Sei froh, dass dich der Compiler angemotzt hat. Das kann nicht richtig
sein.
(Die fehlenden _ zur 100% Übereinstimmung mit dem geposteten Code denke
ich mir jetzt mal dazu)
> ihr habt es ja nicht anders gewollt
Es ist die EINZIGE Möglichkeit, um dubiosen Fehlern auf die Spur zu
kommen!
TLVHead_Def*_pHierarchieStart[HIERARCHIE_DEEP];//!< Startpositionen der Hierarchieebene im Speicher. ebene 0 = Start der Message
2
TLVHead_Def*_pReadPosition[HIERARCHIE_DEEP];//!< Positionen des zulesenden Tag der Hierarchieebene im Speicher
3
TLVHead_Def*_pWritePosition;//!< Positionen andem ein neuer Tag geschrieben wird. Momentan nur Anhängen möglich!
4
TLVHead_Def*_pEndPosition[HIERARCHIE_DEEP];//!< Positionen hinter dem letzten Tag der Hierarchieebene im Speicher
5
TLVHead_Def*_pEndOfBufferPosition;//!< Positionen hinter dem letzten Byte des Speicher
6
TagDefinition_TagHierarchieLevel[HIERARCHIE_DEEP];//!< Array zur Speicherung des Tags der Hierarchieebene
derartig parallel geführte Arrays sind ein klares Indiz, dass dir hier
eine weitere Klassenebene, die der Hierarchie, fehlt. Anstatt 4 (oder
5?) paralele Arrays, sollte das nur 1 Array sein, wobei jedes
Arrayelement einen Hierarchielevel komplett beschreibt.
1
classTLVLevel
2
{
3
TLVHead_Def*pStart_;
4
TLVHead_Def*pReadPosition_;
5
TLVHead_Def*pEndPosition_;
6
TagDefinitionLevel_;
7
};
und in deiner Klasse dann eben
1
....
2
TLVLevelLevels_[HIERARCHIE_DEEP];
3
TLVHead_Def*_pWritePosition;//!< Positionen andem e
4
TLVHead_Def*_pEndOfBufferPosition;//!< Positionen hinter dem letzten Byte des Speicher
ob jetzt die WritePosition mit zu einem HierarchyLevel gehört oder nicht
kann ich mangels Code bzw. Gesamtüberblick nicht beurteilen.
Und ja. Alles Level-spezifische gehört dann in diese neue TLVLevel
Klasse.
Sch... mir ist gerade nach 15min schreiben der Browser abgestürzt und
das ganze Posting ist weg, also noch mal von vorne
das Ganze driftet mir hier ein wenig ab.
1
TLVHead_Def*a;
2
TLVHead_Def*b;
3
4
if(a>=b)
Diese if-Abfrage führt zu dem genannten Fehler. Dies habe ich auch so
compiliert, gerade um Problemem mit anderen Zusammenhängen (z.B. Array)
auszuschließen. In meinen ersten Posting habe ich nur a und b gegen
pWritePosition und pEndPosition um für das Posting einen Bezug zu zwei
Zeigern in einen Speicher herzustellen.
Das Problem was ich habe, ist, das der GCC-Compiler meint ich möchte
zwei Klassen vergelichen, also gar nicht die Pointer miteinander
vergelicht, sondern die Klassen (TLVHead_Def), und die können natürlich
nicht >= sein. Der Keil Compiler hat mein Vorhaben richtig erkannt und
vergelicht die beiden Adressen auf den die Pointer zeigen. Mit den cast
auf void* bekomme ich den GCC davon auch überzeugt, weil jetzt die
Pointer nicht mehr auf Klassen, sondern auf Speicher zeigen.
Ich suche jetzt einen andere Möglichkeit den Compiler von diesen
Vorhaben zu überzeugen (z.B. einenen Optionsparameter beim
Compileraufruf)
Gruß Steffen
Karl Heinz Buchegger schrieb:> class TLVLevel> {> TLVHead_Def* pStart_;> TLVHead_Def* pReadPosition_;> TLVHead_Def* pEndPosition_;> TagDefinition Level_;> };
Den Tip nehm ich dankend zur Kenntniss, so wird das ganze nochmals
übersichtlicher. Hat aber mit dem aktuellen Problem nichts zu tun.
> Ich suche jetzt einen andere Möglichkeit den Compiler von diesen Vorhaben zu
überzeugen
Ich kann mich nur wiederholen:
Zeig deinen richtigen Code und nicht irgendwas, was du fürs Forum
zurecht gemacht hast.
Wenn du etwas für das Forum zurecht machst, dann erstelle ein
vollständiges Beispiel, das man auch als solches durch den Compiler
jagen kann.
ABer Problemcode-Präsentation in homöopathischen Dosen führt zu nichts.
Was mir nicht klar geworden ist, ob das Programm nun ein C++ Programm
ist oder ein C-Programm.
Weiter würde ich im Zweifel eher dem GCC trauen als dem Keil. Lange,
schmerzvolle Erfahrung. Leider.
Hast Du schon mal ein Lint probiert? Nur mal so als Gegenprüfung zum
Keil und GCC.
Karl Heinz Einwand ist jedenfalls sicher kein "Abdriften". Ein Vergleich
eines Zeigers auf ein struct mit einem Zeiger auf ein Array mit Zeigern
auf ein solches struct ist ziemlich sicher ein Fehler; mindestens ein
konzeptioneller - auch wenn's dann "irgendwie" läuft.
Jedenfalls lohnt sich, das mal in Frage zu stellen.
Hmm schrieb:> Was mir nicht klar geworden ist, ob das Programm nun ein C++ Programm> ist oder ein C-Programm.
Das ist sehr eindeutig C++. Der Doppelpunkt-Operator :: und das
Schlüsselwort class sind so kleine, aber deutliche Hinweise darauf.
Steffen Graap schrieb:> TLVHead_Def* a;> TLVHead_Def* b;>> if(a >= b)>> Diese if-Abfrage führt zu dem genannten Fehler.
Bei mir nicht (GCC 4.8.1). Für den Test habe ich der Klasse eine Methode
hinzugefügt, die die obigen Codezeilen und eine leere Anweisung nach der
If-Abfrage enthält.
Vielleicht machst du den Vergleich in einem anderen (illegalen) Kontext.
Versuch doch mal, deinen kompletten Code auf eine nicht allzu große
C++-Datei reduzieren, die beim Kompilieren genau den von dir
beschriebenen Fehler erzeugt. Nur so kann er evtl. von anderen
reproduziert werden.
Edit:
Nach etwas Recherche bin ich fast zum Schluss gekommen, dass der GCC
generell keine Fehlermeldungen der Art "Could not find operator>= for
type bool" ausgibt. Eine Fehlermeldung mit ähnlicher Aussage lautet beim
GCC "no match for 'operator>=' in ...". Bist du sicher, dass du
tatsächlich den GCC und nicht irgendeinen anderen Compiler benutzt?
Yalu X. schrieb:> Versuch doch mal, deinen kompletten Code auf eine nicht allzu große> C++-Datei reduzieren, die beim Kompilieren genau den von dir> beschriebenen Fehler erzeugt. Nur so kann er evtl. von anderen> reproduziert werden.
Die komplette hpp ist ja oben zu sehen. Und wie auch schon etwas weiter
oben gezeig, hier nochmal eine komplette Methode die so Compiliert wird
Yalu X. schrieb:> Nach etwas Recherche bin ich fast zum Schluss gekommen, dass der GCC> generell keine Fehlermeldungen der Art "Could not find operator>= for> type bool" ausgibt. Eine Fehlermeldung mit ähnlicher Aussage lautet beim> GCC "no match for 'operator>=' in ...". Bist du sicher, dass du> tatsächlich den GCC und nicht irgendeinen anderen Compiler benutzt?
Das kann schom möglich sein. Ich benutze eclipse und stoße darüber den
Compiler an. Das Resultat steht dann unter Problems, ob es vom Compiler
kommt oder woanders her, muss ich morgen auf Arbeit mal nachschauen.
Steffen
Steffen Graap schrieb:> Die komplette hpp ist ja oben zu sehen. Und wie auch schon etwas weiter> oben gezeig, hier nochmal eine komplette Methode die so Compiliert wird
Wenn ich deinen Code vom 05.08.2013 18:44 und den vom 05.08.2013 20:50
zusammenfüge und für die undefinierten Symbole HIERARCHIE_DEEP,
TagDefinition und ParamNothing halbwegs sinnvolle Definitionen
hinzufüge, erhalte ich beim Kompilieren keinen Fehler, nur Warnungen,
dass a und b uninitialisiert benutzt werden, was ja auch zu erwarten
ist.
Steffen Graap schrieb:> Ich benutze eclipse und stoße darüber den Compiler an. Das Resultat> steht dann unter Problems, ob es vom Compiler kommt oder woanders her,> muss ich morgen auf Arbeit mal nachschauen.
Verwendest du vielleicht ein Unit-Test-Tool namesn CUTE? Das scheint
Fehlermeldungen ähnlich der von dir beschriebenen zu generieren und das
mitunter auch bei korrektem Code:
http://cute-test.com/issues/72
Yalu X. schrieb:> Verwendest du vielleicht ein Unit-Test-Tool namesn CUTE? Das scheint> Fehlermeldungen ähnlich der von dir beschriebenen zu generieren und das> mitunter auch bei korrektem Code:
Ja, deshalb compiliere ich ja mit GCC, hab ich im ersten Post auch so
beschrieben. Das Compilat für die Hardware wird ja mit dem Keil erzeugt.
Nach den Hinnweisen von gestern Abend und heute Morgen, konnte ich das
Problem tatsächlich in den Einstellungen von eclipse für das CUTE-Plugin
festmachen. Das CUTE-Plugin hat eigenen Einstellung für die
Code-Analyse, welche den Fehler feststellt.
Warum ich fälschlicherweise den GCC als Fehlerquelle im verdacht hatte,
liegt wohl daran, das ich nach compilieren die Fehlermeldungen das erste
mal war genommen hatte. Ein Irtum meiner seits.
Danke für eure Unterstützung, für mich ist das Thema abgeschlossen.
Gruß Steffen