GCC 3.3.6 vs GCC 4.2 - time()

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
Calzo
Linux 1.x
Linux 1.x
Messaggi: 112
Iscritto il: sab 6 ott 2007, 22:21
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE
Località: MN

GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Calzo »

Ciao a tutti.
La domanda è: quale compilatore è meglio e/o cosa è cambiato tra i compilatori in oggetto?

Questa domanda la pongo perchè recentemente mi è capitato di portare alcuni vecchi programmi di esempio da un sistema ad un altro e di ricompilarli. Premetto che il sistema su cui li avevo scritti (che per altro è quello che uso tutt'ora) è una SlackWare 10.2 con compilatore gcc 3.3.6.
I programmi (o meglio il programma visto che è solo uno che da il problema) l'ho portato sotto Mint 6 e ricompilato. Il programma molto semplificato è il seguente:

Codice: Seleziona tutto

/* Assurdo.c: */
#include <stdio.h>
#include <stdlib.h>
int main() {
        int x;

        srand(time());
        printf("%i\n", (int)rand());
        return 0;
}
Il problema stà nella funzione time(). Questo programma sotto Slackware 10.2 funziona perfettamente, mentre sotto Mint 6 (gcc-4.3.2) genera un Segmentation Fault. Anche se la cosa mi è sembrata molto strana, ho letto il man di quelle 3 funzioni scritte nel programma ed effettivamente c'è scritto che time() richiede un puntatore in ingresso, oppure si metta NULL, cosa che io non ho fatto. A questo punto le domande che mi sono posto sono:

1. Perchè in SlackWare 10.2 funziona senza passare nessun parametro?
2. Perchè in sia in Slack che in Mint il compilatore non mi dice che manca un parametro? e perchè se scrivo time(&x, &x, &x) non mi dice che di parametri ce ne sono troppi?
3. Cosa cambia nel codice effettivo?

Bene: mentre alle prime domande non ho risposta, alla terza ho disassemblato il codice del del programma con time(). Il risultato è stato questo:

Codice: Seleziona tutto

Mint 6:
0x0804eaa0 <time+0>:	push   %ebp
0x0804eaa1 <time+1>:	mov    %esp,%ebp
0x0804eaa3 <time+3>:	mov    0x8(%ebp),%edx
0x0804eaa6 <time+6>:	push   %ebx
0x0804eaa7 <time+7>:	xor    %ebx,%ebx
0x0804eaa9 <time+9>:	mov    $0xd,%eax
0x0804eaae <time+14>:	int    $0x80
0x0804eab0 <time+16>:	test   %edx,%edx
0x0804eab2 <time+18>:	je     0x804eab6 <time+22>
0x0804eab4 <time+20>:	mov    %eax,(%edx)
0x0804eab6 <time+22>:	pop    %ebx
0x0804eab7 <time+23>:	pop    %ebp
0x0804eab8 <time+24>:	ret 
time() viene chiamata nel main senza salvare nessun parametro nello stack. Quindi alla riga +20 del codice appena postato è ovvio che crasha perchè va a scrivere in un indirizzo di memoria che al 99,9% non è NULL e quindi "je" (riga +18) non verrà mai eseguito.
Ma cosa succede allora in SlackWare 10.2? Bhè il codice è così:

Codice: Seleziona tutto

SlackWare:
    0x0804e1a0 <time+0>:    mov    %ebx,%edx
    0x0804e1a2 <time+2>:    mov    0x4(%esp),%ebx
    0x0804e1a6 <time+6>:    mov    $0xd,%eax
    0x0804e1ab <time+11>:   int    $0x80
    0x0804e1ad <time+13>:   mov    %edx,%ebx
    0x0804e1af <time+15>:   ret
A parte che è strutturalemente diverso, questo codice non creerà mai problemi. Ed inoltre sono 6 istruzioni contro le 14 di prima!!

Quindi ora riformulo la domanda iniziale: Perchè un compilatore + vecchio mi crea del codice più snello e (a mio dire) robusto, mentre il compilatore più nuovo mi genera codice meno ottimizzato? è cambiato qualche cosa a livello di librerie o di compilatore che non so?

Non so se sono stato chiaro, ma ad ogni modo grazie a tutti in anticipo x le eventuali spiegazioni :)

PS: Stavo per insultare Mint pesantemente insieme a ubuntu e a tutte le sue derivate, quando purtroppo tramite un conoscente ho provato a compilare il programma sotto SlackWare 12.2 e il problama c'è anche lì :cry:

Avatar utente
lamarozzo
Linux 3.x
Linux 3.x
Messaggi: 732
Iscritto il: gio 14 lug 2005, 0:00
Desktop: xfce
Distribuzione: archlinux
Località: Roma

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da lamarozzo »

In generale il passaggio dalla serie 3 a quella 4 di GCC ha portato molti cambiamenti strutturali nel compilatore, praticamente tutti positivi (l'aumento di prestazioni è veramente notevole). Il nuovo compilatore è però molto più rigido riguardo agli standard e cose che prima venivano tollerate ora non lo sono più.

Ad esempio, il tuo codice mi sembra che usi time in modo sbagliato (a meno che non ci sia una funzione time anche in stdlib.h).
Innanzitutto includi la libreria time.h e poi

Codice: Seleziona tutto

#include <time.h>
...
time_t tempo;
(void)time(&tempo);
srand((unsigned long int)tempo);
...
Prova a vedere se così le cose si aggiustano. Inoltre stai compilando con l'opzione -Wall? Un uso improprio di time salterebbe subito fuori.

Ciao.

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Mario Vanoni »

Kernel statico con gcc 4.3.3 funziona,
ma molti programmi compilati con gcc 3.3.6 vanno in TILT,
ricompilandoli con gcc 4.3.3, peggio, crash'ano.

IMVHO anche le libraries (glibc ecc.) vanno prima ricompilate.

Tornato pentito a gcc 3.3.6 di Slackware 12.2.

Avatar utente
Calzo
Linux 1.x
Linux 1.x
Messaggi: 112
Iscritto il: sab 6 ott 2007, 22:21
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE
Località: MN

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Calzo »

lamarozzo ha scritto:In generale il passaggio dalla serie 3 a quella 4 di GCC ha portato molti cambiamenti [...] tutti positivi (l'aumento di prestazioni è veramente notevole). Il nuovo compilatore è però molto più rigido riguardo agli standard e cose che prima venivano tollerate ora non lo sono più.
Infatti anche io sapevo questo, e proprio per questo mi aspettavo che il compilatore mi segnalasse qualche cosa, ma nulla.

Ad ogni modo ho provato a compilare il programma con lemodifiche da te segnalate ed effettivamente torna tutto, ossia il compilatore mi dice che c'è qualche cosa che non va se invoco time() senza e parametri. Quindi ora funziona tutto.
Disassemblando il codice di time(), non vi sono differenze. Insomma: è chiaro che se uno scrivesse software come si deve e non come faccio io, le cose tornerebbero senza problemi :D
Mario Vanoni ha scritto:Kernel statico con gcc 4.3.3 funziona, [...]
IMVHO anche le libraries (glibc ecc.) vanno prima ricompilate.
Non ho capito cosa intendi per kernel "statico" ( :oops: ), però anche secondo me è meglio ricompilare anche le glibc.

Grazie
bye

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Mario Vanoni »

Calzo ha scritto: Non ho capito cosa intendi per kernel "statico"
[ ] Enable loadable module support
e solo make bzImage

Avatar utente
Calzo
Linux 1.x
Linux 1.x
Messaggi: 112
Iscritto il: sab 6 ott 2007, 22:21
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE
Località: MN

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Calzo »

Mario Vanoni ha scritto: [ ] Enable loadable module support
e solo make bzImage
A ok, scusa, avevo pensato un'altra cosa.
Comunque hai detto che ti funziona in quel caso? Bene, ma adesso devo capire perchè 8)

grazie

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Mario Vanoni »

Calzo ha scritto:
Mario Vanoni ha scritto: [ ] Enable loadable module support
e solo make bzImage
A ok, scusa, avevo pensato un'altra cosa.
Comunque hai detto che ti funziona in quel caso? Bene, ma adesso devo capire perchè 8)
Il kernel non usa glibc & co., e` autosufficiente.

Avatar utente
Luci0
Staff
Staff
Messaggi: 3591
Iscritto il: lun 27 giu 2005, 0:00
Nome Cognome: Gabriele Santanché
Slackware: 12.2 14.0
Kernel: 2.6.27.46- gen 3.2.29
Desktop: KDE 3.5.10 Xfce
Località: Forte dei Marmi
Contatta:

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Luci0 »

Mario Vanoni ha scritto:
Calzo ha scritto: Non ho capito cosa intendi per kernel "statico"
[ ] Enable loadable module support
e solo make bzImage
Offtopic: Forse il termine più idoneo é ... kernel monolitico :-)

Ma forse kernel non modulare é forse anche meglio ...

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Mario Vanoni »

Luci0 ha scritto:
Mario Vanoni ha scritto:
Calzo ha scritto: Non ho capito cosa intendi per kernel "statico"
[ ] Enable loadable module support
e solo make bzImage
Offtopic: Forse il termine più idoneo é ... kernel monolitico :-)

Ma forse kernel non modulare é forse anche meglio ...
[OT]

Il kernel Linux e` sempre monolitico, incorpora tutto quello che serve alla macchina,
i kernel Minix e Plan 9 sono microkernel, ogni cosa viene solo aggiunta quando serve.

http://www.osnews.com/story/15960/Intro ... o-MINIX-3/

Di un programma compilato con shared libraries file dice dynamically linked (uses shared libs),
di uno compilato con l'opzione -static dice statically linked.

Quindi un kernel che non carica moduli e` statico,
altrimenti e` un kernel che usa moduli, kernel modulare magari.

Avatar utente
Calzo
Linux 1.x
Linux 1.x
Messaggi: 112
Iscritto il: sab 6 ott 2007, 22:21
Slackware: 10.2 | 13
Desktop: Fluxbox | KDE
Località: MN

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Calzo »

Mario Vanoni ha scritto:Il kernel non usa glibc & co., e` autosufficiente.
Sì ok, ma quando il programma viene linkato le varie funzioni di sistema fino all'istruzione int 0x80 dovrebbero essere definite nelle glibc... quindi se ottimizzo quelle dovrei essere a posto.

...almeno se non ricordo male...
bye

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: GCC 3.3.6 vs GCC 4.2 - time()

Messaggio da Mario Vanoni »

Calzo ha scritto:
Mario Vanoni ha scritto:Il kernel non usa glibc & co., e` autosufficiente.
Sì ok, ma quando il programma viene linkato le varie funzioni di sistema fino all'istruzione int 0x80 dovrebbero essere definite nelle glibc... quindi se ottimizzo quelle dovrei essere a posto.

...almeno se non ricordo male...
bye
Fai confusione tra kernel ed i programmi tuoi.
Il kernel non dipende da glibc, ha i sui strcpy ecc.,
e cambiano magari ad ogni nuova versione.
Un programma tuo:
- compilato con gcc-3.3.6 e glibc compilata con gcc-3.3.6
- compilato con gcc-4.2.4 e glibc compilata con gcc-3.3.6
- compilato con gcc-4.2.4 e glibc compilata con gcc-4.2.4
metti un caso estremo e molto improbabile
- compilato con gcc-3.3.6 e glibc compilata con gcc-4.2.4
i quattro programmi possono dare resultati inattesi.

Rispondi