Wie man sieht wird bei der Derefenzierung des Arrays über
"ptr_b->arr_a[x]" der pointer mit sizeof(arr_t_a) incrementiert anstatt
den anstatt mit sizeof(t_a)...
Irgendwelche ideen/workarounds???
Hab das Problem auch schon auf launchpad gepostet. Nur reagiert da
keiner...
[Mod: Code-Tags ergänzt]
Ma H. schrieb:> Hab das Problem auch schon auf launchpad gepostet. Nur reagiert da> keiner...
Wenn der Code da genauso unleserlich aussieht wie hier, ist das kein
Wunder.
Oliver
Schönes Verwirrspiel hast du da gebaut!
Ma H. schrieb:> Wie man sieht wird bei der Derefenzierung des Arrays über> "ptr_b->arr_a[x]" der pointer mit sizeof(arr_t_a) incrementiert anstatt> den anstatt mit sizeof(t_a)...
Ist doch absolut korrekt, und kein Compiler Bug.
ptr_b->arr_a ist ein Zeiger auf ein Array von Typ arr_t_a. Somit sind
Zugriffe auf ptr_b->arr_a[i] logischerweise immer auf Vielfache der
Größe von arr_t_a.
Natürlich hast du nur 1 Array, somit sind Zugriffe mit i>0 illegal.
Wolltest du vielleicht einfach schreiben:
1
(*ptr_b->arr_a)[i]
So wird erst auf das Array zugegriffen, und dann auf dessen i-tes
Element.
Dann mal so...
vielleicht wird es dann etwas klarer!!
1
uint8_tnumber;
2
ptr_arr_t_apaa=&array_a;;
Zugriff auf das member "number_a" im i-ten Element des "array_a" :
1
number=array_a[i].number_a;
Wie Dr. Sommer korrekterweise gezeigt hat ist
Zugriff auf das member "number_a" im i-ten Element des "array_a" über
den Pointer paa :
1
number=(*paa)[i].number_a;
Es gilt aber auch : (*qualifier).member == qualifier->member
Ist der "qualifier" vom typ "x" als array deklariert,
z.b. "typdef x qualifier[size]"
muß der Compiler zwingend auch den Pointer um sizeof(x) incrementieren
(KR A.7.1)
1
A.7.1.
2
3
If the type of an expression or subexpression is "array of T," for some type T, then
4
the value of the expression is a pointer to the first object in the array, and the type of
5
the expression is altered to ''pointer to T." This conversion does not take place if the
6
expression is the operand of the unary & operator, or of ++, --, sizeof, or as the left
7
operand of an assignment operator or the . operator. Similarly, an expression of type
8
"function returning T," except when used as the operand of the & operator, is converted
9
to "pointer to function returning T."
Sowie KR A7.3
-> group left to right !!!
1
A7.3 Postfix Expressions
2
The operators in postfix expressions group left to right.
3
4
postfix -expression:
5
primary-expression
6
postfix-expression [ expression ]
7
postfix-expression ( argument-expression-listopt
8
postfix-expression . identifier
9
postfix-expression -> identifier
10
postfix-expression ++
11
postfix-expression --
12
13
argument-expression-list:
14
assignment -expression
15
argument-expression-list , assignment-expression
16
17
A7.3.1 Array References
18
19
A postfix expression followed by an expression in square brackets is a postfix expression
20
denoting a subscripted array reference. One of the two expressions must have type
21
"pointer to T', where T is some type, and the other must have integral type; the type of
22
the subscript expression is T. The expression E 1 [ E2] is identical (by definition) to
23
* ( ( E 1 ) + ( E2) ) . See §A8.6.2 for further discussion.
und Auszug KR A.8.6.2
1
A8.6.2 Array Declarators
2
3
.
4
.
5
The array subscripting operation is defined so that E1[E2] is identical to
6
*(E1 + E2). Therefore, despite its asymmetric appearance, subscripting is a commutative
7
operation. Because of the conversion rules that apply to + and to arrays (§§A6.6,
8
A7.1, A7.7), if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th
Ma H. schrieb:> Dann mal so...>> vielleicht wird es dann etwas klarer!!> [gefühlte 100e Zeilen folgen]
Sorry, viel zu lang. Da macht sich keiner die Mühe, das durchzulesen,
geschweige denn auch noch zu verstehen.
Schreibe bitte einen 3-bis-8-Zeiler, der das Problem verdeutlicht und
compilierbar(!) ist.
Dazu noch maximal 3 Zeilen Text. Das reicht.
Ma H. schrieb:> OK.. Ich seh nur Schwätzer hier...!!
Nein, Leute aus der Praxis, die sich so ein undurchdringliches Stück
Code wie da oben nicht freiwillig antun würden.
Hab's gerade versucht, sorry.
Bevor du den Standard zitierst, solltest du erstmal die Begriffe
lernen. Ein "qualifier" ist im Standard etwas ganz anderes als das,
wie du den Begriff hier benutzt (und das stiftet mehr als Verwirrung).
Du kannst dem GCC übrigens ruhig zutrauen, dass er die Zeigerarithmetik
prinzipiell beherrscht, der macht das nicht erst seit gestern.
Ma H. schrieb:> OK.. Ich seh nur Schwätzer hier...!!
Wenn du richtige und zielführende Antworten als Geschwätz ansiehst,
wären dir falsche und irreführende Antworten lieber? Manchmal haben
Experten einen besseren Blick darauf, was Geschwätz ist und was Hinweis.
Du solltest mal versuchen, den Unterschied zwischen dem Pointer auf ein
Array-Element und dem Pointer auf ein ganzes Array zu erkennen.
Weil ich gute Laune habe:
Dein struct-member arr_a ist ein Pointer auf den Typ arr_t_a. Ein
arr_t_a ist ein Array mit MAX_AS=5 Eintraegen von Typ t_a. Also hat GCC
recht, denn du greifst mit &(ptr_b->arr_a[i]) auf das i-te Array arr_t_a
zu (du hast aber nur eins), und nicht auf das i-te Element von deinem
einen Array!
Ein Pointer auf ein Array ist etwas anderes als ein Pointer auf den
ersten Eintrag, du musst einmal öfter dereferenzieren
(*(ptr_b->arr_a))[i].
Falk B. schrieb:> Nein, das ist das gleiche.>> int my_array[10];> int *pointer_to_array = &my_array;
Sicher? Wenn ich das als C Code compiliere kriege ich eine "incompatible
pointer type" Warnung. Als C++ Code compiliert das gar nicht.
Falk B. schrieb:> @ Tassilo H. (tassilo_h)>>>Ein Pointer auf ein Array ist etwas anderes als ein Pointer auf den>>ersten Eintrag,>> Nein, das ist das gleiche
Ist es nicht. Auch wenn die beiden Pointer auf die selbe Speicherstelle
zeigen, haben sie unterschiedliche Typen. Und ein Array ist kein
Pointer...
Oliver
Oliver S. schrieb:> Und ein Array ist kein Pointer...
Zerfällt aber in fast allen Fällen zu einem Pointer. Die einzigen Fälle
in denen es nicht zerfällt ist wenn man den Address-Of Operator drauf
anwendet oder sizeof.
Ma H. schrieb:> Dann mal so...>> vielleicht wird es dann etwas klarer!!
Nein, auch wenn du noch weitere 100 Zeilen hinzufügst, wird das nicht
besser und schon garnicht klarer. Auch nicht mit 3 Ausrufungszeichen.
Ich geb dir nen Rat: Lade dir mal Freepascal und lazarus herunter und
übe 1 Jahr lang mal ordentlich in Pascal zu programmieren. Entweder du
gewöhnst dir dabei an, sauberen und "biederen" Code zu schreiben, was du
dann im Anschluß auch in C tun könntest oder bei dir ist Hopfen&Malz
verloren.
Ich kann es partout nicht ausstehen, wenn Leute beim Codeschreiben
unbedingt irgendwelche grandiosen Husarenstücke vollbringen wollen. Man
kann wirklich ALLES auch auf einfache, eben biedere Art formulieren -
und das wird dann sowohl regelmäßig bedeutend lesbarer als auch von
Anfang an fehlerärmer sein als jede Quellcode-Kunststückchen, wie du sie
weiter oben zu vollführen versuchst.
Also mein wirklich GANZ ERNST gemeinter Rat: Verzichte auf
Kunststückchen und schreib deine Quellen auf einfache Art. Benutze ruhig
auch lokale Variablen zwecks klarerer Lesbarkeit. Dabei kannst du drauf
vertrauen, daß dies deine Firmware nicht verlangsamt, denn der Compiler
kann sowas besser optimieren als du selber.
W.S.