Zeiger auf Literal



  • NDEBUG schrieb:

    ... Wenn ich mir nun also mal laienhaft vorstelle, daß jeder Array Zugriff auf folgende Art und Weise umgewandelt wird

    array[j]
    -> tokenize: token[0] = array, token[1] = j
    -> lea edi, token[0]+token[i]
    

    so erkennt man natürlich sofort daß die eigentlichen Reihenfolge der Werte total egal ist. Warum nicht stärker Typgeprüft wird, habe ich keine Ahnung.

    Muß wohl einen Grund haben und genau der interessiert mich eigentlich schon 😉 . Wenn man's auf dem M16C anschaut, sieht das nach selbem in Grün aus, nur daß der ASM die Addition schon aufgelöst hat:

    // i steht an offset -2 des Framebuffers
    // array[i] = 'c';
        90  0004A  EB4BE6                   	mova	-26[FB],A0	;  array 
        91  0004D  A1B4FE                   	add.w	-2[FB],A0	;  i 
        92  00050  74C663                   	mov.b	#63H,[A0]	; 'c'
    //	i[array] = 'd';
        94  00053  EB4BE6                   	mova	-26[FB],A0	;  array 
        95  00056  A1B4FE                   	add.w	-2[FB],A0	;  i 
        96  00059  74C664                   	mov.b	#64H,[A0]	; 'd'
    

    Mit dem Renesas und KPIT bis auf die Basisadresse identisch, IAR und Tasking hab' ich gar nicht erst probiert, der Compiler wirds wohl ungefähr so wie in Deiner Metasprache auflösen.
    Damit wird zumindest klar, daß an dieser Stelle keine Typenprüfung GEWÜNSCHT ist, fragt sich nur noch, warum, außer dem Wettbewerb um das unübersichtlichste Programm noch ein paar Features zu stiften. 🕶
    Also, wenn es jemand drauf anlegt, bei jedem Arrayzugriff Anker und Index zu vertauschen und dabei mit eingestreuten Pointerdereferenzierungen Verwirrung stiftet, platzt mit ab Zeile 10 der Kopf 😡 .
    Warum zum Henker wird also sowas erlaubt?



  • Der Operator [] ist halt einfach so definiert, dass a[b] gleichbedeutend mit *(a+b) ist, welches (Kommutativgesetzt) gleichbedeutend mit *(b+a) ist, welches in Folge gleichbedeutend mit b[a] ist. Was das hier speziell mit Typprüfung zu tun haben soll... keine Ahnung was du meinst. Im wesentlichen ist das Pointerarithmetik. Was ihr hier noch mit Assemblercode rumwerft verstehe ich auch nicht...



  • Tim schrieb:

    ... Was das hier speziell mit Typprüfung zu tun haben soll... keine Ahnung was du meinst.

    Weil das syntaktisch inkonsistent und verdammt nochmal i kein Array of irgendwas ist.

    Tim schrieb:

    Im wesentlichen ist das Pointerarithmetik. Was ihr hier noch mit Assemblercode rumwerft verstehe ich auch nicht...

    Wenn Du keine Erklärung für die Fragen hast, dann halte Dich einfach an Nuhr und damit den Mund (oder die vorlauten Tippelfinger).



  • pointercrash() schrieb:

    Tim schrieb:

    ... Was das hier speziell mit Typprüfung zu tun haben soll... keine Ahnung was du meinst.

    Weil das syntaktisch inkonsistent und verdammt nochmal i kein Array of irgendwas ist.

    Es ist eine Definition und diese ist konsistent. Wenn dir die Definition nicht gefällt und/oder sie nicht verstehst, kannst du wie so viele andere einen Rant auf youtube stellen.

    Tim schrieb:

    Im wesentlichen ist das Pointerarithmetik. Was ihr hier noch mit Assemblercode rumwerft verstehe ich auch nicht...

    Wenn Du keine Erklärung für die Fragen hast, dann halte Dich einfach an Nuhr und damit den Mund (oder die vorlauten Tippelfinger).[/quote]
    Sorry, ich werde mich in Zukunft zurückhalten deine Wissenslücken zu stopfen. 😉



  • Tim schrieb:

    Der Operator [] ist halt einfach so definiert, dass a[b] gleichbedeutend mit *(a+b) ist, welches (Kommutativgesetzt) gleichbedeutend mit *(b+a) ist, welches in Folge gleichbedeutend mit b[a] ist.

    bekannte tatsachen vorzubeten hilft uns nicht weiter. wir wollen doch wissen, warum man für array[i] auch i[array], aber nicht [i]array hinschreiben kann. ist es ein abfallprodukt irgendwelcher parsing-techniken, ein bug in der syntaxdefinition, oder steckt tatsächlich ein sinn dahinter? dass array[i] das gleiche ist wie *(array+i) erklärt überhaupt nichts. wo sind eigentlich diese ganzen freaks, die hier immer den c-standard vorwärts und rückwärts aufsagen? das muss doch irgendwer wissen.
    🙂



  • Also, bei den untersuchten Compilern (KPIT/Renesas) werden auch außerhalb des Codeblocks definierte statics als Offset des Framebuffers gehandhabt, was auf eine generelle Pointeraddition hinweist, eine MMU gibt es hier nicht.
    Also löst der Compiler a[b] = irgendwas; wohl so nach dem Motto auf "mir brauchen an Pointer, den Typ drauf, machen intern einen sizeof(*typ) und mal dem anderen Kameraden (probeweise kommutativ) und das wird's wohl sein.
    Ich muß es ja nicht mögen, aber verstehen wollte ich's schon. 😉



  • ~fricky schrieb:

    bekannte tatsachen vorzubeten hilft uns nicht weiter. ... das muss doch irgendwer wissen.
    🙂

    Ah, Danke!



  • ~fricky schrieb:

    Tim schrieb:

    Der Operator [] ist halt einfach so definiert, dass a[b] gleichbedeutend mit *(a+b) ist, welches (Kommutativgesetzt) gleichbedeutend mit *(b+a) ist, welches in Folge gleichbedeutend mit b[a] ist.

    bekannte tatsachen vorzubeten hilft uns nicht weiter. wir wollen doch wissen, warum man für array[i] auch i[array], aber nicht [i]array hinschreiben kann.

    Also das [i]array lese ich hier zum ersten Mal. Wo wurde diese Frage schon gestellt? Wie auch immer, was soll daran inkonsequent sein? So ein Konstrukt wurde einfach nicht definiert. Oder fängst du dich gleich an zu wundern warum man pointer nicht so dereferenzieren kann: int a = foo*; ???
    Und den C-Standard kannst du auch selbst lesen. Lächerlicher gehts ja wohl kaum noch...



  • Tim schrieb:

    Also das [i]array lese ich hier zum ersten Mal. Wo wurde diese Frage schon gestellt? Wie auch immer, was soll daran inkonsequent sein? So ein Konstrukt wurde einfach nicht definiert.

    aha. da bitte ich doch mal um quellen!

    [quote=5.2.1]The expression E1[E2] is identical (by definition) to *((E1)+(E2)).[/quote]



  • bis jetzt war es sehr interessant (auch die Kinderstreitereien) zu lesen, aber ich verstehe es noch nicht ganz:

    A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

    dann heißt es E1[E2] ist (nur?) definiert, wenn E1 ein Array/Pointer und E2 ein Interger ist. Aber im Falle i[array] trifft das nicht zu. Hab ich was übersehen?



  • volkard schrieb:

    [quote=5.2.1]The expression E1[E2] is identical (by definition) to *((E1)+(E2)).

    [/quote]
    mehr hab ich auch nicht dazu gefunden (hab' aber nur nach 'subscript' gesucht). jedenfalls sagt das nicht aus, dass e2[e1] oder [e1]e2 auch erlaubt sind.
    🙂



  • uups. [i]array hab ich in diesem thtread immer als i[array] gelesen.

    zu deiner frage, warum [i]array nicht geht, kann ich nur sagen, daß die frage bereits quatsch ist. im mathe fragt man ja auch nicht "warum geht eigentlich "4 / 4" aber nicht "/ 4 4"?".



  • supertux schrieb:

    bis jetzt war es sehr interessant (auch die Kinderstreitereien) zu lesen, aber ich verstehe es noch nicht ganz:

    A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

    dann heißt es E1[E2] ist (nur?) definiert, wenn E1 ein Array/Pointer und E2 ein Interger ist. Aber im Falle i[array] trifft das nicht zu. Hab ich was übersehen?

    ab Because wird nur zusätzlich zum besseren verständnis erläutert, was das bedeutet, falls E1 is an array object[/b] and E2 is an integer.



  • volkard schrieb:

    im mathe fragt man ja auch nicht "warum geht eigentlich "4 / 4" aber nicht "/ 4 4"?".

    könnte man aber. das wäre dann 'reverse polish notation' nochmals umgedreht. langsam wundert mich garnichts mehr.
    🙂



  • ~fricky schrieb:

    volkard schrieb:

    im mathe fragt man ja auch nicht "warum geht eigentlich "4 / 4" aber nicht "/ 4 4"?".

    könnte man aber. das wäre dann 'reverse polish notation' nochmals umgedreht. langsam wundert mich garnichts mehr.
    🙂

    was wohl rauskommt, wenn man was zweimal umdreht?
    nenns doch einfach reverse reverse reverse reverse reverse reverse reverse reverse reverse reverse polish notation.



  • volkard schrieb:

    was wohl rauskommt, wenn man was zweimal umdreht?

    deswegen das 'nochmals'.
    🙂



  • Ich hab's schon verstanden. Wenn man einen enumerativen Typ auf einen Pointer addiert, wird das Ergebnis kommutativ ermittelt, es wird immer pointer + sizeof(pointertyp) * enumerator adressiert. Das ist normale Pointerarithmetik, alles klar.

    Aber beim Subscript hätte man durchaus eine Typenprüfung implementieren können, auch wenn's auf das Selbe *(a+i) == *(i+a) hinausläuft.

    Die Frage lautet daher immer noch, warum das unterlassen wurde. Ich finde diese Frage keineswegs lächerlich und die potentielle Antwort "pure menschliche Faulheit" eigentlich ulkiger 🤡 . Noch unmöglicher finde ich Standard- Herunterbeter, die mißlaunig ein paar Brocken hinschleudern und mangels fachkundiger Antwort Pauschalbeleidigungen hinterher.

    Also vielleicht weiß jemand wirklich, warum da keine Typenprüfung stattfindet, obwohl die leicht zu implementieren wäre?



  • ganz lustig ist auch das:

    int array[3][3] = {{1,2,3},{5,5,6},{7,8,9}};
    
      printf ("%d\n", 1[array][0]);  // geht
      printf ("%d\n", 1[0][array]);  // geht nicht (jedenfalls nicht mit dem vs 2005)
    

    ^^das spricht nicht gerade für irgendwelche hilflosen erklärungsversuche über's kommutativgesetz.
    aber frag doch mal in comp.lang.c. vielleicht gibt's da jemanden, der mehr weiss als 'das ist einfach so'.
    🙂



  • ~fricky schrieb:

    int array[3][3] = {{1,2,3},{5,5,6},{7,8,9}};
    
      printf ("%d\n", 1[array][0]);  // geht
      printf ("%d\n", 1[0][array]);  // geht nicht (jedenfalls nicht mit dem vs 2005)
    

    ^^das spricht nicht gerade für irgendwelche hilflosen erklärungsversuche über's kommutativgesetz.

    [] ist linksassoziativ.



  • Bashar schrieb:

    [] ist linksassoziativ.

    ok, aber klammern helfen auch nicht weiter.
    🙂


Anmelden zum Antworten