Pointer auf Array 2 of int
-
Von welchem Typ ist denn das Ergebnis eines Adressoperators angewendet auf ein int[2]?
-
Ursprünglich hätte ich jetzt gesagt das es die Adresse eines int[2] arrays ist und somit auch passt.
Aber Wutz (und der kennt sich aus) hatte ja geschrieben das es falsch ist wegen UB. Vielleicht stehe ich jetzt auch auf dem Schlauch, das macht mich jetzt echt fertig.
-
pointer_frage schrieb:
Aber Wutz (und der kennt sich aus) hatte ja geschrieben das es falsch ist wegen UB. Vielleicht stehe ich jetzt auch auf dem Schlauch, das macht mich jetzt echt fertig.
Ich weiß auch nicht, was er an der Stelle damit meinte. Vielleicht hat er irgendwo in dem langen Thread etwas anders verstanden, als es gemeint war. (Wobei ich hoffe, dass ich selber nichts übersehen habe)
-
Vielleicht äußert er sich ja nochmal dazu. Ich lass mich leicht verunsichern, ich mach das noch nicht so lange, das wissen oder Unwissen ist noch nicht so gefestigt
-
int arr[2]; int (*p)[2]; p = &arr;
ist natürlich richtig.
Wutz meinte lediglich, dass ich deutlicher hätte schreiben sollen, dass es total falsch ist das & weg zu lassen. Auch wenn es den selben Wert liefert, führt p = arr zu undefiniertem Verhalten. Also blos nicht machen
-
pointer_frage schrieb:
Aber Wutz (und der kennt sich aus)
Oder auch nicht.
-
MatzeHHC schrieb:
int arr[2]; int (*p)[2]; p = &arr;
ist natürlich richtig.
Die Zuweisung (p = &arr) ist durchaus richtig.
Allerdings macht die Deklaration mit Sicherheit nicht das, was der TE erwartet.
p
ist ein Zeiger auf einint[2]
array, und somit liefertp[0]
die Adresse des ersten Array's,p[1]
die Adresse des zweiten Array's usw. :printf("%p\n", p[0]); // Adresse von arr printf("%p\n", p[1]); // Adresse von arr + sizeof(int[2]) printf("%d\n%d\n", p[0][0], p[0][1]); // Werte arr[0] und arr[1]
-
Hatte eigentlich vor, nicht mehr in diesem Thread zu antworten, weil mir das zu kindisch wurde - aber weil Wutz seinen Autismus nicht behandeln lässt, mache ich das eben doch.
An den OP:
1. Online-Compiler? Ja klar. m( DAS ist die Zukunft, ganz bestimmt.
Zur Information: jeder ORDENTLICHE Compiler wirft hier eine Warnung. Weil die Typen unterschiedlich sind Der gcc wirft hier eine. Deiner nicht. Also ist deiner nicht ordentlich.[/virtuellerSchwanzvergleich]Jetzt kann man darüber streiten, wie man die Warnung wegbekommt.
Eine Möglichkeit, die Warnung zu eliminieren, ist die&array
-Methode. Die kann effektiv sein. Muss sie aber nicht. Schon gar nicht in deinem Post, in dem Informationen fehlen. Wo wir so überhaupt nicht wissen, was du eigentlich willst, außer deine finale Aussage, die überhaupt keinen Sinn ergibt.Eine weitere Möglichkeit ist ein Cast.
Wie MatzeHHC schon geschrieben hat, gibt es keinen eigentlichen Unterschied zwischenarray
und&array
. Die Adresse des Arrays ist gleichzeitig die Adresse des ersten Elementes des Arrays. Ein Cast sagt dem Compiler nur, dass er die Fresse halten soll.Oder eine weitere Möglichkeit ist die Analyse des Programms und die Feststellung, dass es hier keinen Grund gibt, ein Array von Zeigern auf Arrays zu verwenden. Das wäre besser rübergekommen, wenn du eine Referenzierung wie unten beschrieben verwendet hättest.
Da Zeiger ein komplexes Thema sind und dein Code nach Anfänger schreit, bin ich davon ausgegangen, dass du etwas versucht hast, was du nicht verstanden hast. Eigentlich gehe ich sogar davon aus, dass du es immer noch nicht weißt.2. Ist es MEIN Problem, wenn du eine kaputte Kommunikation an den Tag legst? Ich zitiere dich:
p ist ein Pointer auf ein Array von 2 Int, scheitert es an der zuweisung?
Das war der zentrale Punkt. Deine Aussage, was in deiner Vorstellung
p
ist, wie du es anwenden willst. Und das ist falsch. Ich bin mir sicher, du hast mein Beispiel nicht mal kompiliert? Eine Ein-Zeichen-Änderungen, die immer noch mit deiner zentralen Aussage kollidiert, war dir lieber? Ich weiß bisher immer noch nicht, ob du Zeiger nur nicht korrekt verstanden hast (wovon ich immer noch ausgehe, weil ich bei der Dereferenzierung des Zeigerst[x][x]
machen würde anstatt(*t)[x]
- weil du ein Array von Zeigern auf Arrays hättest statt einen Zeiger auf ein Array).3. DU willst mir Deklarationen erklären? Du, der es selbst nicht schafft, seine Deklarationen zu erklären? Ich glaub, es hackt.
Klugscheißer
Und warum werden wir gleich beleidigend?
Du hast Glück, keinen angemeldeten Account zu verwenden, sonst käme der in mein Killfile. Jedenfalls hast du gerade die Chance eliminiert, dass ich dir in diesem Thread nochmal helfe.An Wutz:
Ich meine das Ernst, irgendwas stimmt mit dir nicht.
Wenn du mit einer Aussage von mir nicht übereinstimmst, SAG ES, und schreib nur nicht, dass ich falsch liegen würde. Ich erinnere dich an deine Aussage in einem anderen Thread, dass es keinen Unterschied machen würde, ob manunsigned int*
oderunsigned char*
verwendet. Ich habe damals ganz genau widersprochen und gesagt, WIESO es einen Unterschied macht. Mit Beispiel und dem Fehler, den es verursacht.Mit allem, was ich von dir jemals bekommen habe, kann ich meinen Garten düngen. Also sag an, was Sache ist. Mit "ist falsch" kann ich nichts anfangen, mit "halt die Klappe" schon gar nicht. Nein, weißt du was, sag nichts *into the killfile it goes*.
An osdt: +1.
-
dachschaden schrieb:
Eine weitere Möglichkeit ist ein Cast.
Wie MatzeHHC schon geschrieben hat, gibt es keinen eigentlichen Unterschied zwischenarray
und&array
. Die Adresse des Arrays ist gleichzeitig die Adresse des ersten Elementes des Arrays. Ein Cast sagt dem Compiler nur, dass er die Fresse halten soll.Ich bekomm's gerade nicht hin, aber irgendwie ist es bestimmt möglich ein Beispiel zu basteln, wo man damit auf die Fresse fliegt*. Es sind inkompatible Pointertypen. Einen davon in den anderen zu casten und danach lesend darauf zu zu greifen ist undefiniertes Verhalten. Basta.
*: Vielleicht irgendwas mit Unions und zusammengesetzte Typen mit ungerader sizeof, bei gleichzeitig strikten Anforderungen ans Alignment. virtual in all seinen Ausprägungen wäre sicher auch ein guter Kandidat, wenn man C++ in Betracht zieht. Irgendwie gibt es bestimmt eine Kombination, das falsch zu biegen.
-
Dann solltest du dir in keinem Fall die ganzen
sockaddr
-Typen anschauen. Da macht man ständig Casts vonsockaddr_in*
bzw.sockaddr_in6*
oder auch malsockaddr_un*
. Sind alle untereinander zuweisbar.connect
übernimmt zum Beispiel immer nursockaddr*
. Machbar isses auf jeden Fall. Wenn du einen Fehler findest - die glibc-Leute werden sich freuen. Oder vielleicht auch die gcc-Leute, wenn du eine Stelle findest, wo sie das Alignment falsch machen.
-
Dass das in diesen Fällen funktioniert und auch immer funktionieren wird, bestreit ich gar nicht. Ich bin bloß ebenso sicher, dass man irgendwie einen Fall konstruieren kann, wo die Aussage, dass es egal wäre, ob man arr oder &arr schreibt, zu Problemen führt.
(Und dass das Casten von inkompatiblen Pointertypen Probleme verursachen kann, ist trivial zu zeigen.)
-
Mein Post bezog sich auf deine dann doch verallgemeinerte Aussage:
SeppJ schrieb:
Es sind inkompatible Pointertypen. Einen davon in den anderen zu casten und danach lesend darauf zu zu greifen ist undefiniertes Verhalten.
-
@dachschaden: Es ist nicht naheliegend, daß jemals ein Compiler den UB-Code nicht korrekt übersetzt. Eigentlich.
Aaber, anscheinend benutzt der GCC gelegentlich die schärfstmögliche Auslegung des Standards, um UB-Stellen zu finden und wegzuoptimieren. Also irgendwann kriegen sie Dich.SeppJ schrieb:
Ich bin bloß ebenso sicher, dass man irgendwie einen Fall konstruieren kann, wo die Aussage, dass es egal wäre, ob man arr oder &arr schreibt, zu Problemen führt.
Der einer Funktion übergebene Wert ist ja gleich. Da sehe ich wenig Spielraum, eine Funktion in Produktivcode zu schmuggeln, um z.B. openssl wieder aufzumachen.
#include <stdio.h> #include <string.h> //fills any object with zeros. //#define INIT_ZERO(x) memset(x,0,sizeof(*(x))) #define INIT_ZERO(p) testMemset(p,0,sizeof(*(p))) void testMemset(void* p,int v,size_t n){ printf("memset(%p,%u,%zu)\n",p,v,n); } int main() { struct{ int arr[10]; } str; int arr[10]; INIT_ZERO(&str);//ok INIT_ZERO(&arr);//ok //INIT_ZERO(str);//Compilerfehler //error: invalid type argument of unary '*' (have 'struct <anonymous>') //Als alter C-Hase weiß ich ja, daß ich vor Arrays in Aufrufen //das & immer weglassen darf. Außer, SeppJ und volki zetteln //eine Verschwörung an… INIT_ZERO(arr);//Kein Compilerfehler. //Löscht leider nur 4 Bytes statt 40. return 0; }
-
@Volkard:
Jau, bin ich bereit, anzuerkennen. Danke dafür.
-
volkard schrieb:
Der einer Funktion übergebene Wert ist ja gleich. Da sehe ich wenig Spielraum, eine Funktion in Produktivcode zu schmuggeln, um z.B. openssl wieder aufzumachen.
Ich dachte da an irgendwas in der Richtung, wie in C++ bei Mehrfachvererbung und Casts zu Pointern auf die Basisklasse und der Compiler generiert tatsächlich Code für den Cast, der einem die passende Basisklasse gibt. Damit kann man bestimmt irgendwie Schabernack treiben. In reinem C geht da vielleicht auch irgendwie was mit krummen Alignments wo man vielleicht am Ende einen Pointer auf eine falsch ausgerichtete Adresse bekommt. Aber wie gesagt, habe ich noch kein konkretes Beispiel ausgeknobelt.
-
1. Online-Compiler? Ja klar. m( DAS ist die Zukunft, ganz bestimmt.
Zur Information: jeder ORDENTLICHE Compiler wirft hier eine Warnung.Wahnsinn Alter, du bist so behämmert das es nur kracht. Checkst du es wirklich nicht ? Lesen... Typischer Fachidiot. Wie er im Buche steht.
Du kannst Dir gar nicht vorstellen wie egal es mir ist wie Du irgendetwas tust. Kauf dir ein Stück Kuchen und freu dich darüber das du so ein guter C- Programmierer bist.
Und warum werden wir gleich beleidigend?
Du hast Glück, keinen angemeldeten Account zu verwenden, sonst käme der in mein Killfile. Jedenfalls hast du gerade die Chance eliminiert, dass ich dir in diesem Thread nochmal helfeJa hoffentlich !!! Ich bitte sogar darum das du in gar keinem Thread mehr irgendwem hilfst. Lass es einfach.
Und Wutz hat vollkommen recht : Halt die Klappe.
*into the killfile it goes*.
Ob er da noch ruhig schlafen kann....
==>> Bitte jmd. den Thread schließen, hier ist alles gesagt. (Bis auf Mister D. war es auch alles hilfreich. ) .
-
pointer_frage schrieb:
Wahnsinn Alter, du bist so behämmert das es nur kracht. Checkst du es wirklich nicht ? Lesen... Typischer Fachidiot. Wie er im Buche steht.
Vorsicht! Damit beleidigst Du richtige Fachidioten wie mich.
pointer_frage schrieb:
==>> Bitte jmd. den Thread schließen, hier ist alles gesagt. (Bis auf Mister D. war es auch alles hilfreich. ) .
Schließen ist hier unüblich. Und diesen jetzt sicher nicht, denn es steht noch die spannende Frage offen nach weiterem Code, der arr != &arr ausnutzt.
-
Hallo volkard, ich würde dich NIE als FachIdioten bezeichnen. Ich glaube du weißt ziemlich genau was ich gemeint hatte