Zeiger auf Literal



  • 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.
    🙂



  • das geht auch:

    printf ("%d\n", 1[array[0]]);  // geht
    printf ("%d\n", 1[0[array]]);  // geht
    

    🙂



  • Bashar schrieb:

    [] ist linksassoziativ.

    Und genau deswegen gehört da eine Typenprüfung hin!

    Ich vermute fast, ich werde keine sinnvolle Begründung zu lesen bekommen, warum die fehlt. Es ist wohl so, weil es so ist, standardgewordener Hedonismus der C-Narzissten, sich in der selbstgeschaffenen Kryptik zu suhlen und das auch noch konsistent zu finden. Ist ja prinzipiell nix Neues, aber dieser Punkt war mir bislang unbekannt.



  • pointercrash() schrieb:

    Bashar schrieb:

    [] ist linksassoziativ.

    Und genau deswegen gehört da eine Typenprüfung hin!

    Logik? Wieso "genau deswegen"?



  • Bashar schrieb:

    pointercrash() schrieb:

    Bashar schrieb:

    [] ist linksassoziativ.

    Und genau deswegen gehört da eine Typenprüfung hin!

    Logik? Wieso "genau deswegen"?

    Wenn eine Zuordnung eindeutig sein könnte, soll sie es auch sein, um Fehler zu vermeiden. Die Logik, das kommutativ zu gestalten, ist grundsätzlich in Zweifel zu ziehen, weil sie dann hier scheitert

    array[i] = 'c';		// Arrayzugriff
    	i[array] = 'd';		// Arrayzugriff
    	*(array+i) = 'e';	// direkte Pointerarithmetik, OK
    	*(array-i) = 'f';	// direkte Pointerarithmetik, formal OK, für '-i' wird '+ abs(i)' verwendet
    //	*(i-array) = 'g';	// [Error(ccom)] invalid '-' operands
    

    Da steht viermal das Gleiche da, die fünfte Darstellung wird verweigert. Das ist keine konsistente Abbildung auf den zu erwartenden Ergebnisraum, also bedarf es da einer Regel, die es nicht gibt. Es ist ja keine echte mathematische Subtraktion, sondern Pointerarithmetik, die nur auf die Nase fällt, weil sie ausgerechnet hier über die Nichtkommutativität der Subtraktion stolpert. Das ist unstimmig. Weshalb die Subtraktion davor so geschluckt wird, ist sowieso der Hammer.
    Spätestens nach frickys willkürlichen Chaoscode- Basteleien hätte Dir der Sinn einer Typprüfung einleuchtend sein müssen. 😃



  • Aha, aber das hatte ich nicht gefragt.



  • [quote="pointercrash()"]

    *(array-i) = 'f';	// direkte Pointerarithmetik, formal OK, für '-i' wird '+ abs(i)' verwendet
    

    unfug. minus ist minus und braucht keine plus-bedeutung.

    //	*(i-array) = 'g';	// [Error(ccom)] invalid '-' operands
    

    [/cpp]
    logo. a-i ist ja auch was ganz anderes als i-a.
    zum beispiel ist 13-8 was ganz anderes als 8-13.



  • ich hab grad mal versucht, das hier zu durchschauen: http://www.lysator.liu.se/c/ANSI-C-grammar-y.html#translation-unit
    danach ist ein array-zugriff eine sogenannte 'postfix-expression' gefolgt von []. dummerweise kann diese eine 'primary-expression' sein, die wiederum nicht nur 'identifier' sondern auch 'konstante' sein darf. im innern der [] darf eine 'expression' sein, die alles mögliche darstellen kann (ich hab' die verzweigungen nicht genau verfolgt). es sieht's fast so aus, wie ein (wahrscheinlich unvermeidbarer) systembedingter fehler, weil sich da rekursionen bzw. schleifen eingeschlichen haben. es fehlen aber noch einschränkungen, wie's scheint. kennt sich hier jemand mit dieser darstellung aus?
    🙂



  • Das hier ist interessant. Von ~frickys Quelle:

    int check_type()
    {
    /*
    * pseudo code --- this is what it should check
    *
    *	if (yytext == type_name)
    *		return(TYPE_NAME);
    *
    *	return(IDENTIFIER);
    */
    
    /*
    *	it actually will only return IDENTIFIER
    */
    
    	return(IDENTIFIER);
    }
    

    EDIT: Bezieht sich aber wohl nur auf Deklarationen/Definitionen, sprich DCLs und hat mit dem Typchecking was in diesem Thread gewünscht wird nix zu tun.



  • volkard schrieb:

    pointercrash() schrieb:

    *(array-i) = 'f';	// direkte Pointerarithmetik, formal OK, für '-i' wird '+ abs(i)' verwendet
    

    unfug. minus ist minus und braucht keine plus-bedeutung.

    Ergebnis ist Ergebnis, die drei getesteten Compiler machen *(array+i) draus. Das Ganze ist ein Riesenunfug, da stimme ich Dir schon zu, aber den behaupte ich nicht, den produzieren meine Compiler.

    volkard schrieb:

    pointercrash() schrieb:

    //	*(i-array) = 'g';	// [Error(ccom)] invalid '-' operands
    

    logo. a-i ist ja auch was ganz anderes als i-a.
    zum beispiel ist 13-8 was ganz anderes als 8-13.

    Na klar, Du Held! Darin liegt ja die Inkonsistenz. Man leitet sich die Kommutativität von der mathematischen Addition ab und die Nichtkommutativität von der Subtraktion, daraus folgende Hirnrisse werden zurechtgehämmert. Dabei haben '+' (pointer+enum) und '+' (z.B. Int + Int) je nach Teilnehmer eigentlich gar nichts miteinander zu tun.
    Das ist ganz schlimmer Schwachmatenkram, ganz miserabel durchdacht, in Pascal gäb's die Todesstrafe dafür.
    Aber nicht mal 'ne gescheite Typenprüfung gibt's in C für subscript, das ist erbärmlich.


Anmelden zum Antworten