Newsgroup: it.comp.lang.c
Titolo: Che significa? :-)

ciao a tutti, che può significare la seguente linea di codice:
p = &(*((unsigned short *)0x00256500));
esiste un modo per semplificarla e renderla più leggibile?

 esiste un modo per semplificarla e renderla più leggibile?
#define HW_LOC        (*(unsigned short*)0x00256500)
p = &HW_LOC;
B.

 spazio memoria mappato flat, se no avresti un segment fault.
Ma avendo dichiarato p come puntatore a ushort, non sarebbe stata la 
stessa cosa scrivere direttamente:
p = 0x00256500;
?
-- 
God is real, unless if declared integer.
Powered by Debian GNU/Linux


Dipende dal compilatore. Se 0x00256500 fosse veramente un indirizzo di
memoria mappato (quindi, niente errori di concetto nella riga) a
seconda del compilatore e del grado di ottimizzazione potrebbe o non
potrebbe effettuare la lettura.
Innanzi tutto direi che definire una macro non sia una cattiva idea:
#define ADDRESS ((volatile unsigned short *)0x00256500)
Se si vuole solo l'indirizzo:
p = (unsigned short *)ADDRESS;
Se invece si vuole effettuare la lettura e tornare il valore
dell'indirizzo in p converrebbe (almeno per aumentare la leggibilità)
farlo separatamente:
q = *ADDRESS;
p = (unsigned short *)ADDRESS;
No?


In realta' non so se l' OP ha dichiarato p come pointer ;-)
O forse nelle intezioni dello scrivente originale la forma sembrava
piu' chiara ... avrei capito di piu' se l' intenzione fosse quella di usare
direttamente l' indirizzo, ad esempio nel modo seguente:
#define PSEUDO_VAR   (*(unsigned short*)0x00256500)
  unsigned short  val;
   val = PSEUDO_VAR;
etc...
B.

 In realta' non so se l' OP ha dichiarato p come pointer ;-)
Beh, gli viene assegnato un indirizzo, cosa potrebbe essere se non un 
puntatore?



Un qualsiasi tipo intero abbastanza grande da contenere un indirizzo
(un unsigned?). Magari un registro.


mai supporre troppo, si potrebbe rimanere sorpresi ... ;-)
B.


Ma in questo caso il compilatore non dovrebbe dare *almeno* un warning 
di assegnamento tra variabili di tipo diverso o una cosa del tipo "cast 
implicito tra int e address"? (ora non ricordo il warning esatto, ma mi 
pare una cosa del genere)


 esiste un modo per semplificarla e renderla più leggibile?
p=(unsigned short *)0x00256500;
E.


Sono settaggi del compilatore, che non fanno parte dello standard c
(che prevede un errore in caso di questo tipo di assegnamenti).
Comunque ad esempio, il gcc con l'opzione -ansi compila e dà:
warning: assignment makes integer from pointer without a cast
mentre con -pedantic-errors non compila e dà:
error: assignment makes integer from pointer without a cast


A stringere probabilmente sì, a parte strani settaggi di un qualsiasi
compilatore moderno il codice macchina delle due espressioni sarà
equivalente.

fma...@gmail.com
 ha scritto:

Se p è un puntatore allora &*p è la stessa cosa di p. Che altro 
significato gli puoi dare?!?
E.

 significato gli puoi dare?!?
Forse si riferisce al fatto che un compilatore particolarmente tonto 
potrebbe generare codice anche per le due operazioni che si elidono a 
vicenda mentre uno mediamente furbo se ne accorge e non genera codice.
ciao
Giacomo

 
fmas...@gmail.com
 ha scritto:

Il C è un linguaggio procedurale, non descrittivo: non importa "cosa
significa" ma "quello che fa". In questo caso a seconda della
piattaforma si possono avere degli effetti collaterali (come la
lettura effettiva dalla memoria). Giusto per dare un'idea, ho provato
sulla mia macchina (un x86) a compilare con gcc (ma ogni compilatore
dovrebbe fare uguale) il seguente codice:
#include <stdio.h>
int main()
{
    unsigned char *p, *q;
    p = &(*q); /* cosa fa? */
    putchar(*p);
    return 0;
}
Compilando con l'opzione di massima ottimizzazione (-O3) si ottiene:
a1 20 a0 04 08          mov    0x804a020,%eax
Mentre senza (-O0):
8b 45 f8                mov    -0x8(%ebp),%eax
89 45 f4                mov    %eax,-0xc(%ebp)
Anche se la dimostrazione non è strettamente legata al linguaggio C
direi che in pratica è abbastanza convincente, almeno per me.

Giacomo Degli Esposti ha scritto:

Ma l'operatore & non genera codice macchina, è una operazione che viene 
eseguita durante la compilazione. Questo perchè il concetto di variabile 
non esiste in linguaggio macchina. Anche l'operatore * non genera 
direttamente codice. Serve ad indicare che ci si sta riferendo ad una 
certa locazione di memoria. Ma se questa vada letta/scritta o ignorata, 
dipende da quello che ci fai in seguito.
E.

 direi che in pratica è abbastanza convincente, almeno per me.
Io non capisco il codice generato, me lo puoi spiegare? Comunque il test 
che andrebbe fatto è confrontare il codice per p=&*q con il codice per p=q.
E.

 ?manu* wrote:

un compilatore qui non deve generare codice:
6.5.3.2 §3
The unary & operator returns the address of its operand. [...] If the
operand is the result of a unary * operator, neither that operator
nor the & operator is evaluated and the result is as if both were
omitted, except that the constraints on the operators still apply and
the result is not an lvalue.
cc

 the result is not an lvalue.
ovvero se non e' possibile assegnare il risultato dell' operazione ...

 p= &*q ---> p=q;          //&* non sono valutati ;-)
Scusate, era quello che volevo dire. Grazie per la correzione.
Saluti dalla germania.
cc (tuttora imparando l'italiano)


Veramente a me il codice del primo esempio non ha alcun senso o in 
ogni caso non è relativo al C, mentre il secondo esempio mostra 
appunto lo statement p = q;
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >

 > cc (tuttora imparando l'italiano)
Grüße, leider weiß ich nicht Deutsch
B.


Si, hai ragione, avrei dovuto mettere un altro po' di righe per far
capire che succedeva :) Comunque l'operazione successiva (la chiamata
di putchar()) prevedeva il push del valore sullo stack, che veniva
preso da eax, quindi c'era qualcosa del tipo: pushl %eax  - call
0xqualcosa.
Non mi ricordavo comunque del punto dello standard che specificava
proprio questo caso.. Con quel paragrafo tutto è risolto!