Strukturen vergleichen
-
c-hasser&# schrieb:
noobLolo schrieb:
c-hasser&# schrieb:
...Damit keine Missverständnisse aufkommen: Memcmp ist für den Vergleich von Strukturen im Allgemeinen ungeeignet...
Nein, nicht "immer", höchstens "meistens" oder "fast immer" :p
also zwei strukturen des gleichen typs lassen sich super vergleichen
Nein, das funktioniert eben nicht; auch nicht bei Strukturen des gleichen Typs - wegen der Paddingbits.
ja an die dacht ich auch schon, könnte es nicht sein das die genullt werden oder so? werd mal versuchen was im standard zu finden... das wird wieder ne odyssee...
evtl. hat da ja jmd. einen anhaltspunkt wo man suchen sollte?lg lolo
-
6.2.6.1.6 schrieb:
When a value is stored in an object of structure or union type, including in a member
object, the bytes of the object representation that correspond to any padding bytes take
unspecified values.okay ich gebe nach
lg lolo
-
Falls irgendjemand diesen Post wie ich über google o.Ä. findet. Die richtige Lösung wurde noch nicht gepostet.
In C++ ist die korrekte Vorgehensweise ein Compare Operator*:
http://www.learncpp.com/cpp-tutorial/94-overloading-the-comparison-operators/* in C++ ist eine Struktur nichts weiter als eine Klasse mit public membern.
-
Das hier ist aber das C Unterforum.
-
Achso...
ja dann gibt es keine "richtige" lösung.
Am besten aber so (da am allgemeinsten):
***Zensiert durch SeppJ. So nämlich am besten nicht***Bei memcmp(a, b, sizeof()) muss man sonst immer achten das die Struktur packed ist.
-
Doch, es gibt die richtige Lösung: Jeder Member wird einzeln verglichen.
Zu dem LinK: Scheiss Beispiel.
Postleitzahlen sind keine Ganzzahlen.
-
Wenn du Objekte miteinander vergleichst, musst du erstmal definieren, was Gleichheit bedeutet und wie diese zu ermitteln ist.
Z.b. zwei Äpfel. Wann sind 2 Äpfel gleich?
Antwort: kommt auf die Parameter an, die man vergleicht.
Wann ist ein Apfel und eine Birne gleich?
Antwort: kommt auf die Parameter an, die man vergleicht. Generell kann man sagen, nein, aber wenn ich als Vergleichsmerkmal nutze, dass zwei Objekt genau dann gleich sein sollen, wenn sie Früchte sind, dann ist Apfel und eine Birne gleich.
Lange Rede kurzer Sinn: Bei abstrakten Strukturen wie deine, musst DU zunächst definieren, WAS man vergleicht und welche Vergleichsmerkmale jeweils verwendet werden. Deswegen macht es eine bit-für-bit Gleichheit keinen Sinn.
-
supertux schrieb:
Bei abstrakten Strukturen wie deine, musst DU zunächst definieren, WAS man vergleicht und welche Vergleichsmerkmale jeweils verwendet werden. Deswegen macht es eine bit-für-bit Gleichheit keinen Sinn.
Cool:
Erst sagst Du, was Gleichheit ist, bestimmt allein der Autor, und im nächsten Satz bestimmst plötzlich Du, was (keinen) Sinn macht ...
-
In der Tat habe ich mich nicht besonders gut ausgedruckt. Klar ist meine Aussage, der Autor muss definieren, was "gleich" ist und wie man es testet.
Ich wollte aber sagen, dass (hier im Falle von "wie") bitweises Vergleichen bei Strukturen nicht OK sind, z.B. wegen padding bits wie erwähnt wurde.
-
Konnte man nicht das Padding ausschalten und/oder per Hand erledigen? Automatismen sind ja nicht immer wünschenswert.
-
Autowech schrieb:
Konnte man nicht das Padding ausschalten und/oder per Hand erledigen? Automatismen sind ja nicht immer wünschenswert.
Könnte man, aber wieso sollte man das wollen? Bloß um beim Vergleich faul sein zu dürfen? Das Padding ist ja nicht bloß da, um den Programmierer zu ärgern.
-
SeppJ schrieb:
Autowech schrieb:
Konnte man nicht das Padding ausschalten und/oder per Hand erledigen? Automatismen sind ja nicht immer wünschenswert.
Könnte man, aber wieso sollte man das wollen? Bloß um beim Vergleich faul sein zu dürfen? Das Padding ist ja nicht bloß da, um den Programmierer zu ärgern.
Umsonst wird man kaum eine Option in den Compiler eingebaut haben um das Padding zu deaktivieren.
-
Autowech schrieb:
SeppJ schrieb:
Autowech schrieb:
Konnte man nicht das Padding ausschalten und/oder per Hand erledigen? Automatismen sind ja nicht immer wünschenswert.
Könnte man, aber wieso sollte man das wollen? Bloß um beim Vergleich faul sein zu dürfen? Das Padding ist ja nicht bloß da, um den Programmierer zu ärgern.
Umsonst wird man kaum eine Option in den Compiler eingebaut haben um das Padding zu deaktivieren.
Aber der Grund ist nicht, Vergleiche einfacher zu machen.
-
SeppJ schrieb:
Autowech schrieb:
SeppJ schrieb:
Autowech schrieb:
Konnte man nicht das Padding ausschalten und/oder per Hand erledigen? Automatismen sind ja nicht immer wünschenswert.
Könnte man, aber wieso sollte man das wollen? Bloß um beim Vergleich faul sein zu dürfen? Das Padding ist ja nicht bloß da, um den Programmierer zu ärgern.
Umsonst wird man kaum eine Option in den Compiler eingebaut haben um das Padding zu deaktivieren.
Aber der Grund ist nicht, Vergleiche einfacher zu machen.
Aber würde das fehlende Padding nicht den Vergleich von Strukturen mit memcmp auch schneller machen?
-
Jo, und alles andere, was mit den Strukturen, bzw. Zugriffen auf die Member zu tun hat, langsamer ...
-
Autowech schrieb:
Aber würde das fehlende Padding nicht den Vergleich von Strukturen mit memcmp auch schneller machen?
Aber das würdest Du Dir ja zu Ungunsten des Compilers erkaufen, der die Struktur nicht nach seinem Gusto optimieren darf.
Abgesehen davon ist der bitweise Vergleich relativ schnell uninteressant - z.B. bei Zeigern oder strings in
char[]
.
-
Autowech schrieb:
Aber würde das fehlende Padding nicht den Vergleich von Strukturen mit memcmp auch schneller machen?
Tatsächlich kann das Padding den Vergleich sogar schneller machen. Wenn das Padding eine Struktur beispielsweise von 56 auf 64 Bit vergrößert, kann der Compiler das
memcmp
eventuell mit einem 64-bitcmp
umsetzen, anstatt mit dreicmp
, die jeweils 32, 16 und 8 Bit umfassen. Das setzt natürlich voraus, dass der Compiler an der Stelle die Werte der Padding-Bytes kennt. Da deren Werte aber implementationsdefiniert sind, kann ein Compiler da einiges machen.Das Einsparpotential durch den Verzicht auf Padding ist nie so groß, dass es Operationen auf einzelnen Instanzen beschleunigen könnte. Man kann Strukturelemente immer so umsortieren, dass ein minimales Padding am Ende der Struktur entsteht. Wenn die Struktur zum Beispiel ein Alignment von 8 erfordert, kann maximal Padding-Overhead von 7 entstehen.
Wenn eine Struktur Padding hat, ist ein einfaches
memcmp
natürlich sinnlos, weil das Ergebnis unvorhersehbar ist.
Denkbar wäre aber eine Compiler-Erweiterung, die dasmemcmp
des relevanten Anteils erlaubt.struct s { uint32_t a; /*_Padding(0) verbietet es dem Compiler das Offset eines Elementes durch Padding zu verändern.*/ _Padding(0) uint16_t b; _Padding(0) uint8_t c; /*Falls die Struktur für das Alignment Padding erfordert, muss dieses hinter end eingefügt werden. end zeigt dann genau auf den Beginn des eventuellen Paddings.*/ _Padding(0) char padding[]; }; struct s first, second; /*end beginnt genau da, wo der sinnvoll vergleichbare Anteil der Struktur aufhört*/ memcmp(&first, &second, offsetof(struct s, padding));
-
Ok, dann scheint deaktiviertes Padding wirklich nur Sinn zu machen, wo man auf jedes Byte achten muss.
Ich habe mal gelesen, dass es eh darauf ankommt cachefreundlich zu programmieren. Es hieß man sollte jeden Zugriff auf den wirklich langsamen Hauptspeicher vermeiden soll. Kontrolle ist also alles bei der Optimierung.
-
Der Haupteinsatzzweck ist eher, dass man durch Abschalten des Paddings ein 100% vorhersehbares Layout der structs erreicht (gleiche Größe der Datentypen vorausgesetzt), so dass dieses garantiert binärkompatibel zwischen unterschiedlichen Plattformen ist (gleiche Endianess und ähnliches vorausgesetzt).
-
SeppJ schrieb:
Der Haupteinsatzzweck ist eher, dass man durch Abschalten des Paddings ein 100% vorhersehbares Layout der structs erreicht (gleiche Größe der Datentypen vorausgesetzt), so dass dieses garantiert binärkompatibel zwischen unterschiedlichen Plattformen ist (gleiche Endianess und ähnliches vorausgesetzt).
Mit anderen Worten, es ist gar nichts garantiert.
Man spart sich lediglich etwas Tipparbeit, wenn man sich auf plattformspezifische Details verlässt.