Newsgroup: it.comp.lang.c
Titolo: Re: array subscripting e simmetria (Was: [?][PUNTATORI] ...)

 bel giochino, sbagliato ma divertente.
Non credo che sia sbagliato.
Non ho indagato molto... ma nel documento dello standard C99 mi sembra 
che non ci sia nulla che vieti questa simmetria riguardo l' array 
subscripting.
Nel 'C99 Rationale' rev. 5.10 del 2003, invece, e' riportata questa frase:
     6.5.2.1
     - The C89 Committee found no reason to disallow the symmetry
     that permits a[i] to be written as i[a].
Quindi parrebbe tutto valido.
PS: ovviamente la questione e' di dubbia utilita'... ma se per 
curiosita' vuoi fare una veloce prova con il tuo compilatore:
     printf("%c\n", 3["ABCDEFG"]);
(dovrebbe stampare "D\n" nello std. output)
Ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

 ...
Di ragioni per cui questa simmetria non esiste affatto ne
esistono molte; ho gia` ricordata una, un'altra e` questa:
a[i] e` solo un notazione per l'operatore estrazione di 
indice, altre notazioni valide potrebbero  essere i[a], a_i,
a(i), extract_element_by_index(a,i) et cetera.
Stabilire  quale di queste sia la migliore e` una guerra di
religione; la cosa che realmente importa e` di sceglierne
una che non sia ambigua, che non entri in contrasto con 
altre parti del linguaggio, che non sia troppo sovraccarica, 
che non sia troppo lontana dal linguaggio naturale, non 
generi confusione negli utenti. 
Pero` a mio avviso adottare due notazioni diverse (come a[i] 
ed i[a]) per la stessa identica cosa entra in contrasto con
parecchie di queste cose. 

 niente a che vedere con a[i].
http://c-faq.com/aryptr/joke.html
Ciao.

 Non credo che sia sbagliato.
io credo che i compilatori si possano in cazzare per la tipizzazione.

 io credo che i compilatori si possano in cazzare per la tipizzazione.
Non esiste nessun problema di tipizzazione!
Come già detto E1[E2] equivale a *((E1) + (E2)).
Se E1[E2] non ha problemi di tipo nemmeno *((E1) + (E2)) ne ha.
Essendo la stessa cosa.
Quando dico che non ci sono problemi di tipo intendo dire
che E1 o E2 è un puntatore ad "object type" e l'altro
è di tipo intero.
E' ovvio dal contesto che ci stiamo focalizzando
solo nei casi in cui E1[E2] ha senso.
--
Giorgio Silvestri
DSP/Embedded/Real Time OS   Software Engineer

 Come già detto E1[E2] equivale a *((E1) + (E2)).
Secondo me non è proprio giusto quello che scrivi perché
mio_tipo_dato_t vettore[10];
vettore[5] equivale a *(vettore + 5 * sizeof (mio_tipo_dato_t))
a me è successo di fare casino passando da [] a *() dimenticandomi di
scalare per il numero giusto di byte l'offset.
quindi fare 5[vettore] non so se e come abbia senso o se ti ritrovi con
qualcosa come *(5 + vettore * sizeof(int))
secondo me rischi di perdere significato....
Se giochi con gli interi mantiene il suo significato, ma secondo me cade
altrimenti.

 qualcosa come *(5 + vettore * sizeof(int))
5[vettore] ha senso ed equivale a *(5 + vettore).
Ti consiglio un buon libro sul C (es: K&R2) e un buon ripasso
sui puntatori e la loro aritmetica correlata.


 è di tipo intero.
Infatti. E nei vincoli o imposizioni (constraints) non viene specificato 
quale sia l'uno o l'altro:
     ISO/IEC 9899:1999 (E)
     6.5.2.1 Array subscripting
     *Constraints*
     1. One of the expressions shall have type "pointer
     to object /type/", the other expression shall have
     integer type, and the result has type "/type/".
Anzi, da quello che si puo' leggere ("One of the expressions ...the 
other ...") la simmetria sembra proprio intenzionale.


 [snip]
...ma, "in sostanza", che volevi dire?
Se mi spieghi meglio magari posso anche risponderti.


 *(vettore + 5)
Pardon, siamo partiti da due punti diversi:
#include <stdio.h>
typedef struct
{
  char primo;
  char secondo;
} mio_dato_t;
int main () {
  mio_dato_t vettore[3];
  mio_dato_t *p;
  p = vettore + 2 ;
  printf ("vettore %u\n", vettore);
  printf ("p %u\n", p);
  return 0;
}
ed esegui ti viene fuori una cosa del tipo
bott@banach:/tmp$ ./prova
vettore 
3219158522
p 
3219158526
se però la somma di + 2 la forzi tra interi facendo
  p = (int) vettore + 2 ;
allora come risultato avrai qualcosa come
vettore 
3219799706
p 
3219799708
e cadi nel oggetto di indice 1.
La mia è deformazione mentale e non è aritmetica dei puntatori, ma ti
assicuro che in alcune applicazioni, video processing nel mio caso,
ragionare nel secondo caso è molto più comodo pensando al blobbone di
byte e spostarsi con l'intero usato come offset.
Comunque sì, hai ragione.

 e cadi nel oggetto di indice 1.
puo' darsi, ma non e' detto...
Tu cosi' scrivi codice assolutamente non portabile.


 Tu cosi' scrivi codice assolutamente non portabile.
perché? sia ben chiaro, non è polemico, anzi mi interessa molto.

Ottavio Campana ha scritto:

(neanche il mio era un post polemico)
Cercando di essere conciso, nel codice che hai postato si capisce che 
dai come certi almeno i segg. punti:
- che il valore di un puntatore possa essere assegnato con sicurezza ad 
un (signed) int; che un int possa contenerlo; e che quindi il puntatore 
possa essere ricostruito partendo dal valore di un int
- che la struttura 'mio_dato_t' (contenendo due 'char') abbia dim. 2 byte
- che quindi il secondo elemento dell'array 'vettore' (contenendo 
strutture di tipo 'mio_dato_t') si trovi a 2 byte di offset dal primo 
elemento
Queste sono tutte ipotesi che dipendono dall'architettura e dal 
compilatore utilizzato (ed alcune, talvolta, anche dalle opzioni di 
compilazione).


 compilazione).
ah sě, ok, pensavo fosse chiaro quando ho scritto che non avevo altre
architetture su cui fare le prove.
Per quanto, per esperienza con avri compilatori/architetture non ho mai
visto allineare in modo esotico i char usati cosě, che poi č come si
usano per il video.