Newsgroup: it.comp.lang.c
Titolo: Domandine stupide...

Avrei qualche piccolo quesito che non mi fa dormire la notte...
1) se linko vari files oggetto compilati separatamente che utilizzano stesse
funzioni e quindi stesse intestazioni, viene ripetuto del codice, o il
linker sa cosa fare..?
2) l'accesso ad una zona di memoria rispetto ad un'altra può essere più
veloce (a parte le var memorizzate come register...). Intendo, ad esempio,
un var globale potrebbe essere più lenta o più veloce di una memorizzata
nello stack? Le costanti come vengono memorizzate?
3) Le variabili register, oltre nei cicli, dove sono usate più spesso(motori
3D?)? Quante register potrebbe contenere un PII? Leggendo le caratteristiche
del nuovo PIII ho letto di nuovi registri x i float. C'entra qualcosa?
4) Sto usando il manuale di Shildth, ma c'è una cosa che non mi è chiara :
che significa "il compilatore inserisce una costante numerica nel più
piccolo tipo di dati compatibile in grado di contenerla"? Nel capitolo 2.8
si riferisce ai valori assegnati alle variabili, come li chiama nel
paragrafo precedente, o al modificatore const, o cos'altro? Poi, quale
sarebbe la necessità di assegnare ad esempio 34L invece di 34, se comunque
ho già definito nell'intestazione della variabile il tipo e l'eventuale
modificatore 8in questo caso long)?
Infine, se ad una var assegno un valore ottale o esadecimale, lo posso poi
convertire o stampare in un altro formato?
5) usare un incremento (tipo x++) invece dell'equivalente assegnamento
(x=x+1) produce un programma più veloce. Se devo sommare un valore diverso
da 1, usando un for, magari con variabili register, sarebbe più veloce di un
normale assegnamento con incremento (tipo x=x+4)? Perché? Ci sono altri modi
per farlo? (non conosco l'assembler, quindi non so in quante istruzioni sono
tradotti i vari comandi C ...a proposito, in assembler, o anche in
linguaggio macchina, ogni istruzione è veloce come le altre, no?)
6) Quali sono le differenze tra un programma in modalità reale e lo stesso
in modalità protetta? Cambia la velocità, o le risorse utilizzate? O
cos'altro?
7) In un processore a 64 bit, tipo il futuro Merced della Intel, o il RISC
della Playstation, quanto occupa una word, etc..?
8) esiste qualche libro con esercizi e quesiti per argomenti (il libro di
Kerningham e Ritche è cosi?)?
Grazie mille per le risposte!!!!(mi sa che ho rotto un pò troppo, ma magari
le risposte potrebbero essere utili anche ad altri neofiti...)
Marco Iannaccone

 Kerningham e Ritche è cosi?)?
Ore di trace su un debugger in assembler ed analisi del codice asm
prodotto da un compilatore + una attenta lettura dei manuali Intel sono
la migliore palestra.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/
       Search, Read, Discuss, or Start Your Own    

Kerningham e Ritche è cosi?)?
Il Kernighan & Ritchie II versione e' cosi'.
Andrea Laforgia
*************************************************
Cerca sempre di percorrere una strada contromano.
Sara' piu' difficile prenderti alle spalle.
*************************************************

Non e' vero.
"La maggior parte dei compilatori C produce un codice oggetto molto
efficiente per le operazioni di incremento e decremento, molto migliore
rispetto a quello generato utilizzando l'equivalente operatore di
assegnamento."
C la guida completa - Herbert Schildt - pag. 39
--
Francesco Trotta
http://space.tin.it/computer/ftrotta
Elimina "x_" dal mio indirizzo per mandarmi
un messaggio direttamente

 della Playstation, quanto occupa una word, etc..?
[...]
Se non mi sbaglio, il processore della PlayStation e' un MIPS R3000, ed
e' a 32 bit, ossia le word sono di 32 bit.
Ciao, Luca.
-- 
*******************************************************
       "Dio non e' morto.
        E' vivo e sta lavorando
        a un progetto
        meno ambizioso"
				    graffito anonimo
  Reply to 
bia...@maganet.net
*******************************************************

 wrote:
[ snip ]
FT>"La maggior parte dei compilatori C produce un codice oggetto molto
FT>efficiente per le operazioni di incremento e decremento, molto migliore
FT>rispetto a quello generato utilizzando l'equivalente operatore di
FT>assegnamento."
FT>C la guida completa - Herbert Schildt - pag. 39
Appunto, Schildt...non e' una garanzia di qualita' ;)
L'affermazione di cui sopra forse era vera (molti) anni fa, ma adesso e' 
una sciocchezza.
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

C la guida completa - Herbert Schildt - pag. 39
Herbert Shildt e' famoso per dire una marea di cazzate... ;)

Herbert Shildt e' famoso per dire una marea di cazzate... ;)
Come spieghi, allora, che in un linguaggio come il C, famoso per essere "il
più essenziale possibile", l'esistenza dell'incremento e decremento al posto
dell'equivalente assegnamento? Concorderai che non è per rendere il codice
più snello (3 caratteri contro 5).


piů snello (3 caratteri contro 5).
Invece, mi spiace deluderti, ma e' esattamente per quello.
Nonostante il C, come giustamente affermi, abbia una sintassi
essenziale, un'operazione come l'assegnazione (vedasi a = a + 1) deve
essere gestita per forza.
In piu' si puo' introdurre qualche scorciatoia (solo a livello di
codice, ma non di velocita' di esecuzione) per la riscrittura di
determinate operazioni di assegnazione.
Semanticamente un'operazione di pre/post-incremento rimane a tutti gli
effetti un'operazione di assegnazione (sul K&R infatti e' trattata
come tale).
A livello di sintassi, poi, quale altra utilita' vedi nell'uso di "!"
al posto di "not" o "&" al posto di "and" o "int" al posto di
"integer" che non sia la pura stringatezza del codice per velocizzare
il lavoro di scrittura dello stesso (a scapito magari della lettura),
piuttosto che la sua esecuzione.
A conferma di cio' ti cito Bruce Eckel il quale ha scritto nel suo
splendido "Thinking in C++" :
"C, and therefore C++, are full of shortcuts. Shortcuts can make code
much easier to type, and sometimes much harder to read. Perhaps the
designers thought it would be easier to understand a tricky piece of
code if your eyes didn't have to scan as large an area of print.
One of the nicer shortcuts is the auto-increment and auto-decrement
operators. You often use these to change loop variables, which control
the number of times a loop executes.
The auto-decrement operator is -- and means "decrease by one unit."
The auto-increment operator is ++ and means "increase by one unit." If
A is an int, for example, the expression ++A is equivalent to A = A +
1."
 

 piů snello (3 caratteri contro 5).
Considera questo
miaVariabile[ mioContatore ] = miaVariabile[ mioContatore ] + 1
contro questo
miaVariabile[ mioContatore ]++
Quale preferisci? :-)
EMG

Perché non è più così?
Marco Iannaccone

Si, mi sono confuso col processore del Nintendo 64!
Ciao,
Marco

> paragrafo precedente, o al modificatore const, o cos'altro?
Penso che capendo questo capirei anche quello che viene dopo...
Ciao,
Marco Iannaccone

>> paragrafo precedente, o al modificatore const, o cos'altro?
Non si riferisce ai valori assegnati alle variabili e tantomeno a
quelli specificati con "const", in quanto in entrambi i casi il tipo
della costante numerica e' specificato (nel primo caso viene
convertito), nel secondo e' esplicito.
Si riferisce alle costanti numeriche che appaiono in espressioni del
tipo :
if (a != 2.0) ...
A dire il vero, ho il forte dubbio che quanto abbia detto l'autore sia
vero, in quanto in questo caso, secondo lui, si dovrebbe considerare
2.0 come float che e' appunto il piu' piccolo tipo di dato compatibile
(e quindi il piu' piccolo tra i floating point) in grado di contenere
la costante.
Mentre normalmente costanti di questo tipo sono assunte double, quindi
a doppia precisione, anziche' singola.
Come al solito Herbert Shildt non si smentisce.

Perché oggi i compilatori hanno degli algoritmi di ottimizzazione del codice
molto più avanzati di tempo fa (grazie al progresso hardware che riduce
sempre più i tempi di calcolo... anche per i compilatori!!!)
Quindi oggi i migliori compilatori riconoscono e ottimizano un x=x+1 tanto
quanto un x++.
TobiX

 miaVariabile[ mioContatore ]++
o anche:
miaVariabile[funzione(num_a,num_b,num_c)+espressione_molto_lunga]++
senza il ++ bisognava dichiarare una variabile temporanea da usare come
indice!
(notevole spreco, non trovi? :-)
TobiX

 wrote:
MI>Perché non č piů cosě?
Qualsiasi compilatore appena decente e' in grado di accorgersi
che 'x++' e 'x=x+1' fanno la stessa cosa, e dunque sono trattate
allo stesso modo.
Molti anni fa, quando i compilatori non erano cosi 'bravi' ;),
puo' essere che 'x++' e 'x=x+1' venissero trattate diversamente, 
magari solo in alcuni casi...
...ma tutto cio' e' ormai solo leggenda ;)


Grazie mille, veramente non ci avevo pensato!
Comunque, questa volta, l'autore non ha sbagliato, dato che specifica che
alla regola del più piccolo, ci sono 2 eccezioni.
Gli interi anche minori di 256 vanno in un integer, mentre quelli in virgola
mobile comunque in un double...
Grazie, e ciao!
Marco Iannaccone


E in un processore a 128 bit (tipo quello del Dreamcast o della futura
Palystation 2), una word occupa 128 bit, no? E una short int? E una long
int? E poi, quinto occupano questi due tipi in un processore a 64 bit?

E poi, quinto occupano questi due tipi in un processore a 64 bit?
Non si puo' dire con precisione.
Ogni macchina ha le sue caratteristiche.
L'unica cosa certa e' la relazione d'ordine tra le grandezze, cioe'
e' sicuro che
sizeof char <= sizeof short <= sizeof int <= sizeof long
Questo significa che potrebbero essere lunghi *tutti* 64 bit.
(anche se, normalmente, si assicura che il tipo char sia lungo 1
byte).


I tipi definiti nel linguaggio hanno una lunghezza in bit standard.
Poi sta al compilatore mettere un BYTE, tanto per fare un esempio,
in un intero registro di macchina (potenzialmente sprecando spazio),
oppure in altre "locazioni" dipendenti dal processore.
Nel DreamCast la word-(parola di macchina) sara' 128 bit, quindi il
compilatore per il processore per DreamCast dovra' introdurre un tipo
non standard (_int128 ?) per supportare in modo nativo questa tipo
di dato.
Occorre distinguere tra quello che dice lo standard sulla lunghezza
dei tipi, e come questi tipi vengono trattati dal compilatore-processore.
Non so se il compilatore Merceded metta un byte in un registro a 64 bit
(sprecandone 56), so che lo standard C (e C++) prevede che le operazioni
tra BYTE siano operazioni tra interi con segno a 8 bit.


 byte).
Se non vado errato č garantito dallo standard che sizeof( char ) sia
uguale a uno.
EMG

I tipi definiti nel linguaggio hanno una lunghezza in bit standard.
Non e' vero.
La lunghezza in bit varia da implementazione a implementazione.
Non si puo' dire che un "long" abbia lunghezza *standard* di 32 bit,
perche' su una determinata macchina potrebbe essere lungo 64 bit.
Forse vuoi dire che 32 bit e' il minimo assumibile.
La macchina in questione assume con naturalezza che un long, per
esempio, sia lungo 128 bit.
Chi puo' impedirglielo ?

uguale a uno.
Infatti so anch'io cosi'.

 int? E poi, quinto occupano questi due tipi in un processore a 64 bit?
Si', una word occupa 128 bit, ma il resto e' dipendente
dall'implementazione della macchina, nel senso che non lo puoi sapere a
priori; guarda questo esempio:
Char                  1 byte         8 bit
Signed Char           1 byte         8 bit
Unsigned Char         1 byte         8 bit
Short                 2 byte        16 bit
Int                   4 byte        32 bit
Long                  4 byte        32 bit
Unsigned Short        2 byte        16 bit
Unsigned              4 byte        32 bit
Unsigned Long         4 byte        32 bit
Float                 4 byte        32 bit
Double                8 byte        64 bit
Long Double          12 byte        96 bit
Compilato ed eseguito su Intel Pentium 133
Questa cpu e' a 32 bit, ma le dimensioni dei dati non sono deducibili da
questa caratteristica, bisogna andare a vedere *di persona* come vengono
implementati.


...

come al slito si è superficiali.
x++
e
x = x + 1
NON SONO ASSOLUTAMENTE LA STESSA COSA!!!!!
il compilatore qundi non è detto che esegua sempre la stessa
ottimizzazione!!!
ciao achille

,

Mi pareva di ricordare che byte, short, long sono fissi,
mentre int e' lasciato alla implementazione.
Cosi' int su un 286 e' 16 bit, mentre su alpha e' 64, mentre long
e' sempre 32 bit. Se insisti dovro' proprio documentarmi.


NON SONO ASSOLUTAMENTE LA STESSA COSA!!!!!
Be' certo, il primo e' piu' facile da scrivere.
Non vedo altre differenze.
Il seguente programma esegue un benchmark per stabilire quel dei due
metodi venga ottimizzato meglio :
Risultato sulla mia macchina (Pentium133) e compilato con DJGPP :
media (i++) = 5.580000 secs
media (i = i + 1) = 5.580000 secs
--
#include <stdio.h>
#include <time.h>
int main()
{
    unsigned long i, limit = 123456789L ;
    unsigned j, max = 100 ;
    double media = 0.0 ;
    time_t start, end ;
    for ( j = 0 ; j < max ; j++ )
    {
        i = 0L ;
        start = time ( NULL ) ;
        while ( i < limit ) i++ ;
        end = time ( NULL ) ;
        media += difftime ( end, start ) ;
    }
    media /= max ;
    printf ( "media (i++) = %f secs\n", media ) ;
    media = 0.0 ;
    for ( j = 0 ; j < max ; j++ )
    {
        i = 0L ;
        start = time ( NULL ) ;
        while ( i < limit ) i = i + 1 ;
        end = time ( NULL ) ;
        media += difftime ( end, start ) ;
    }
    media /= max ;
    printf ( "media (i = i + 1) = %f secs\n", media ) ;
    return 0 ;
}


BRAVO
hai scritto un programma che non serve a nulla!
studiati questo!!!
y = x++;
y = x = +1;
OK !

Ehm..., se permetti, ...insisto io! Nel senso che mi interesserebbe molto la
risposta!...
Marco Iannaccone

y = x = +1;
???
Non vedo cosa c'entri con la questione di cui si sta parlando.

e' sempre 32 bit. Se insisti dovro' proprio documentarmi.
Come fa ad essere int a 64 bit e long a 32 bit ???
Se int e' a 64 bit, long deve essere *almeno* a 64 bit... 

,

Pag 74 e 75 dello Stroustrup:
int is implementation defined
char is at least 8 bit
short is at least 16 bit
long is at least 32 bit.
Are implementation defined the following assignments:
char c=12345;
short s=75689;
vengono poi definite alcune diseguaglianze sulle
lunghezze di char, short, int , long
bool, long
char, wchar_t , long
float, double, long double


Grazie!
Marco Iannaccone

long is at least 32 bit.
char is *at least 8 bit*
questo significa che char e' ALMENO 8 bit, short ALMENO 16 bit e long
ALMENO 32 bit.
Non significa che siano grandezzze fisse...

,

Va bene, mi scuso per la disinformazione fornita in precedenza.
Pero', a parziale scusante, ho assunto un atteggiamento dubbioso,
sono andato a controllare, e ho postato qualcosa di buono.


 mailto:
gar...@usa.net
 <
- >ICQ UIN# 23780140 <-

Cmq , non capisco nemmeno io cosa c'entri quest'ultimo esempio con x=x+1...
Evidentemente il nostro amico si e' confuso... ;)

come tale).
no. X++ restituisce X. E' (X++) che restituisce X+1.
--Marco++ (chissa' quanto restituisce...)

no. X++ restituisce X. E' (X++) che restituisce X+1.
Guarda che (X++) restituisce il valore di X !!! non X+1 !
Sono davvero stanco di ripetere sempre le stesse cose.
Scrivere l'istruzione 
i++; 
equivale a scrivere 
i = i + 1;
Se, invece, prendiamo il caso di uno statement del genere :
while (t[j++] == s[i++]) ;
Lo pseudo codice corrispondente sara' :
1 - salvo il valore di j in un registro A
2 - prelevo t[A] nel registro C
3 - incremento A
4 - salvo il valore di A in j
5 - salvo il valore di i in un registro B
6 - prelevo s[B] nel registro D
7 - incremento B
9 - salvo il valore di B in i
9 - se C == D salta a 1
10 ...
Il caso complementare di :
while (t[j] == s[i]) 
{ 
       j = j + 1 ; 
       i = i + 1 ; 
}
1 - salvo il valore di j in un registro A
2 - prelevo t[A] nel registro C
3 - salvo il valore di i in un registro B
4 - prelevo s[B] nel registro D
5 - se C != D salta a 10
6 - incremento A
7 - salvo il valore di A in j
8 - incremento B
9 - salvo il valore di B in i
10 ...
Come vedi, la seconda versione e' solo la riscrittura in ordine
diverso delle prime istruzioni (cambia solo il controllo).
A livello semantico l'operazione e' la stessa e viene intesa in
entrambi i casi come un'assegnazione.

via !!! ;)
Ho sottomano "Linguaggio C" di Kernighan e Ritchie e Tricky C.Da quello che ho sentito sul
NG quest'ultimo non e' granche',io mi trovo molto bene...:-)


while (t[j++] == s[i++]) ;
infatti se scrivi while (t[j = j+1] == s[i = i+1]) non ottieni la stessa
cosa.
Cioe', se x++ e' una istruzione allora e' equivalente a x = x+1, ma se la
metti dentro una espressione non e' la stessa cosa. Ossia non puoi
sostituire ovunque a x++ la x = x+1.
Che poi x++ sia come la panda (se non ci fosse bisognerebbe inventarla) sono
pienamente d'accordo.
un esempio di shortcut del linguaggio e' dato dalle istruzioni +=, -= ecc.
In questo caso esse sono definite come x = x+y; x = x-y ecc.
X++ non e' invece "definito" come x = x+1.
si potrebbe definire al piu' cosi':
int    x, t;
x++ equiv. (t=x, x = x+1, t)
Marco

X++ non e' invece "definito" come x = x+1.
Esatto, ma il principio su cui si basa e' comunque quello
dell'assegnazione di un valore ad x.
Ovvio, poi, che x++ non costituisce un lvalue.

 i = i + 1;
Se permetti non sono d'accordo:
++i
equivale a
i = i + 1
i++
equivale a
(i = i + 1,  i - 1)
TobiX

(i = i + 1,  i - 1)
E' sbagliato.
Il codice per i++ non e' quello per (i = i + 1, i-1) tant'e' vero che,
nonostante il seguente codice :
i = i++ ;
non abbia un comportamento definito per lo standard, scrivere
i = (i = i + 1, i - 1) 
non e' affatto la stessa cosa !

 non e' affatto la stessa cosa !
in effetti qui ti do ragione.
certo che è un esempio un po' "estremo"...
ad ogni modo, (passando per un momento al C++) se tu dovessi implementare
l'operatore ++ postfisso per una classe numerica (che so io... int64 ad
esempio) come lo faresti?
TobiX

un valore, la prima un'altro valore (minore di 1)
Questo l'ha mai negato nessuno ?
E sopratutto : si discute di questo nel thread ?
Si discute del fatto se sia *maggiormente* ottimizzabile un
procedimento (i++) o l'altro (i = i + 1) e se da cio' derivi una
maggiore velocita' di esecuzione.
Questo e' falso.

...
Ti sei perso una parte
:(


ICQ #34602650

Attenzione. E' proprio a livello semantico che non sono la stessa cosa.
E' comunque un'assegnazione.
E' questo che voglio dire.

:(
???