o Zeiger sind keine Skalare, sondern eben Zeiger.
o XOR macht Mist wenn die Adressen übereinstimmen.
> Mich interessiert nur, warum das nicht erlaubt ist.
Weil's im C(++) Standard steht.
Lars R. schrieb:> Kaj schrieb:>> Warum genau ist die xor-Operation auf Pointer nicht zulaessig?>> Weil das Unsinn ist (Speicheradressen verwürfeln.)
Nach Sinnhaftigkeit war nicht gefragt!
Wenn es in Assembler (Adressarithmetik,-berechnung) möglich sein, warum
weigert sich der Compiler? Vorrauseilender Gehorsam im Sinne der MMU?
Weil die Designer das so entschieden haben. Du wirst feststellen müssen,
dass praktisch alle binären mathematischen Operationen zwischen 2
Pointern nicht erlaubt sind - es ist in praktisch jedem Fall ein Fehler
des Programmierers, der dazu führt. Und wenn es unbedingt trotzdem sein
muss, kann ein einfacher cast, quasi als "ich weis was ich da mache",
die Einschränkung aushebeln...
Guardians of the memory space schrieb:> Lars R. schrieb:>> Kaj schrieb:>>> Warum genau ist die xor-Operation auf Pointer nicht zulaessig?>>>> Weil das Unsinn ist (Speicheradressen verwürfeln.)>> Nach Sinnhaftigkeit war nicht gefragt!> Wenn es in Assembler (Adressarithmetik,-berechnung) möglich sein, warum> weigert sich der Compiler? Vorrauseilender Gehorsam im Sinne der MMU?
Das hat nichts mit Verweigerung zu tun, man hat sich bei der
Standardisierung von C überlegt welche Operatoren für Adresstypen
benötigt werden und oh wunder xor ist nicht dabei, weil es keinen
Anwendungsfall dafür gibt. In C (und überall sonst wo) sind Zeiger eben
keine Skalare. In Assembler ist das möglich, weil Adressen und alles
Skalare sind, eine CPU kennt keine Datentypen im klassischen Sinne,
deshalb ist das in Assembler möglich.
Kaj schrieb:> Mich interessiert nur, warum> das nicht erlaubt ist.
Wenn es technisch sehr einfach möglich wäre zu verhindern, dass ein
Autofahrer sein Fahrzeug gegen einen Baum lenken kann, fändest du es
dann sinnvoll oder nicht, dieses Feature in jedes Auto einzubauen?
Baldrian schrieb:> So geht es:
Aber nicht auf einem x86_64, denn da sind Pointer größer als Integer.
Wenn schon mit uintptr_t.
Guardians of the memory space schrieb:> Wenn es in Assembler (Adressarithmetik,-berechnung) möglich sein
Pointer müssen nicht notwendigerweise Adressen beinhalten, sondern
können auch mithilfe irgendeiner anderen Form von Referenz implementiert
sein. Daher macht eine XOR-Operation darauf keinen Sinn. Ohnehin sind
nur ganz bestimmte wenige Pointerarithmetiken wohldefiniert.
Zum Tauschen zweier Werte gibt es std::swap. Das funktioniert auch mit
Pointern.
Dr. Sommer schrieb:> Baldrian schrieb:>> So geht es:> Aber nicht auf einem x86_64, denn da sind Pointer größer als Integer.
Irrelevant. Wichtig ist, dass es auf meinem System funktioniert.
Baldrian schrieb:> Irrelevant. Wichtig ist, dass es auf meinem System funktioniert.
Genau, wer kommt schon auf die Idee Software zu verkaufen sodass sie
auch auf dem System des Kunden läuft. Oder sich einen neuen Computer
zuzulegen.
Ich vermute das liegt auch daran, das keine 'normale' Arithmetik
stattfindet. Der numerische Wert von ein Pointer + Zahl ist der
numerische Wert des Pointers plus die Size des Pointertyps mal Zahl.
D.h. wenn man mit dem Bitmuster arbeiten will kann man ja immer noch
casten.
Dr. Sommer schrieb:> Baldrian schrieb:>> Irrelevant. Wichtig ist, dass es auf meinem System funktioniert.> Genau, wer kommt schon auf die Idee Software zu verkaufen sodass sie> auch auf dem System des Kunden läuft. Oder sich einen neuen Computer> zuzulegen.
Danke, dass du mir zustimmst.
Nebenbei: Ich gestatte dir, unter Nennung meines Urheberrechtes und der
Zahlung von angemessenen Tantiemen, mein Programm in deinem Sinne zu
erweitern und zu verkaufen. Viel Glück.
Operatoren sind in C irgendwie definiert.
Sie sind sogar überladen und funktionieren bei unterschiedlichen Typen
ganz unterschiedlich, auch wenn versucht wird, das ganze in sich stimmig
zu halten.
int *pi;
int i;
pi++ macht etwas ganz anderes als i++. genauso ist es mit i+3 und
pi+3. Warum sollte also das mit dem XOR anders sein.
TriHexagon schrieb:> Das hat nichts mit Verweigerung zu tun, man hat sich bei der> Standardisierung von C überlegt welche Operatoren für Adresstypen> benötigt werden und oh wunder xor ist nicht dabei, weil es keinen> Anwendungsfall dafür gibt.
Doch, gibt einen.
Du kannst eine doppelt verkettete Liste mit nur einem Pointer pro
Element basteln, wenn du bei jedem Element "PREV XOR NEXT" speicherst.
Durchlaufen der Liste geht in beide Richtungen, man muss nur immer den
letzten Pointer aufheben, um den nächsten zu errechnen...
Εrnst B. schrieb:> Durchlaufen der Liste geht in beide Richtungen, man muss nur immer den> letzten Pointer aufheben, um den nächsten zu errechnen..
Na sowas. Das ginge aber auch mit "next - prev". Nur leider darf man
keine Pointer subtrahieren die nicht in das selbe Array zeigen...
Ulli N. schrieb:> Wenn es technisch sehr einfach möglich wäre zu verhindern, dass ein> Autofahrer sein Fahrzeug gegen einen Baum lenken kann, fändest du es> dann sinnvoll oder nicht, dieses Feature in jedes Auto einzubauen?
sinnvoller den Baum zu nehmen als am Abhang dem Baum auszuweichen.
Ein wesentlicher Grund, wieso Pointer im C-Standard so eingeschränkt
sind: Das müssen technisch gesehen nicht unbedingt Integer sein.
Besonders bei Architekturen, die über Segment und Offset arbeiten, oder
mit Banks.
Das sind dann Implementationsfragen, von denen C gerade abstrahieren
soll.
Nop schrieb:> Ein wesentlicher Grund, wieso Pointer im C-Standard so eingeschränkt> sind: Das müssen technisch gesehen nicht unbedingt Integer sein.> Besonders bei Architekturen, die über Segment und Offset arbeiten, oder> mit Banks.
Bis hin zu Zeigern, bei denen bestimmte Werte komplett ungültig sind und
nicht mal ohne Hardware-Exception in ein Adress-Register geladen werden
können. Da könnte dann so ein temporäres XOR-Ergebnis schon das ganze
Programm zum Absturz bringen.
> Das sind dann Implementationsfragen, von denen C gerade abstrahieren> soll.
Richtig.
Guardians of the memory space schrieb:> Wenn es in Assembler (Adressarithmetik,-berechnung) möglich sein, warum> weigert sich der Compiler? Vorrauseilender Gehorsam im Sinne der MMU?
Nein (bzw. auch, je nach Architektur).
Hauptsächlich wegen Typensicherheit.