Newsgroup: it.comp.os.linux.sys
Titolo: Problema con gcc

Ho la Slack 10.2 per AMD64 (
www.slamd64.com
), quando provo a compilare
qualcosa, di solito mi va tutto bene, ma ieri ho provato a compilare sia
Xorg6.9, sia tidy (
tidy.sourceforge.net
) e tutti e 2 mi hanno dato il
seguente tipo di errore:
EINVAL function udeclared
ENOMEM function udeclared
ENOENT function udeclared
Guardando il codice ho visto che o erano le uscite di certe funzioni:
return -ENOMEM;
oppure controlli
if (x == ENOMEM)
Guardando su internet ho letto che sono delle uscite standard quando ci sono
dei problemi con i programmi, io per non saperne molto le ho trasformate
in :
return "ENOMEM" ;
oppure 
if (x == "ENOMEM")
e cosi' via.
Ho fatto bene? 
Il programma tidy si e' compilato a meravilgia, ma non so se e' perche',
forse, gcc vuole specificato meglio il tipo di dato, o forse il baco
risiede da qualche altra parte.
-- 
Quigley's Law:
 Whoever has any authority over you, no matter how small, will
atttempt to use it.

 Ho fatto bene? 
no!  EINVAL ed ENOMEM sono valori interi.  semplicemente manca, nel
sorgente, lo statement #include del file che li dichiara, e che e'
<errno.h>.
tipicamente il sorgente e' per una vecchia versione del compilatore,
ed include dei files che a loro volta includevano <errno.h>; mentre
nella tua versione del compilatore non e' piu' cosi'.
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg

 Ho fatto bene?
No, hai fatto male :)
return ENOMEM;
significa
"esci con codice numerico di errore (standard) memoria insufficiente"
return "ENOMEM";
significa
"esci con un codice indefinito"
Lancia ./configure per accertarti che venga rilevata la directory degli 
include e tutto il resto, se non va includi a mano errno.h
Ciaotutti,
*
-- 
If you are sending a reply to a message or a posting be sure you
summarize the original at the top of the message, [...] But do not
include the entire original! -- RFC 1855 - Netiquette Guidelines

 "esci con un codice indefinito"
no.  significa "esci restituendo un puntatore ad un array di const
char, convertito presumibilmente ad intero (e quindi magari troncato);
l'array contiene in questo istante ENOMEM\0 e si trova in una zona di
memoria che verra' liberata e probabilmente riusata appena sarai
uscito".


Ho fatto bene? 
No. Il fatto che ti compili senza warning e' preoccupante, vuol dire che
il compilatore non sta attivando dei warning che dovrebbe avere attivi.
"ENOMEM" con le virgolette e' una stringa, trasformata in puntatore e di
qui a valore intero; sicche'
	x == "ENOMEM"
diventa, in realta', qualcosa come
	x == 0xdeadbeef
che non sara' mai vero, salvo miracoli; e quando sara' vero, segnalera',
con tutta probabilita', come "errore" una situazione di "tutto OK".
Poi ti funziona senz'altro, perche' finche' di memoria ce n'e', l'errore
ENOMEM non si verifica e quel controllo non serve a nulla. Ma, il giorno
che ti servisse, che il grande Cthulhu ti protegga :-)
ENOMEM e' una costante; bisogna scoprire dove e' definita, per esempio a
forza bruta:
	$ grep -ri ENOMEM /usr/include/*
Trovi un padellino di file dove e' usata o definita... quelli riferiti a
programmi o applicazioni specifici, li ignori.
Ma per esempio io trovo:
.../asm-generic/errno-base.h:#define ENOMEM 12 /* Out of memory */
A questo punto, siccome "asm-generic" e' una directory assai di sistema,
vuol dire che viene inclusa da qualche altro file piu' legittimo; cosi',
a occhio, da "errno.h", ma se uno non lo sa cerca il nome del file
	$ grep -ri errno-base.h /usr/include/*
...vede che e' incluso da asm-generic/errno.h, prosegue
	$ grep -ri asm-generic/errno.h /usr/include/*
...vede che e' incluso da asm/errno.h, prosegue e alla fine trova
/usr/include/linux/errno.h:#include <asm/errno.h>
/usr/include/bits/errno.h:# include <linux/errno.h>
/usr/include/errno.h:#include <bits/errno.h>
...e quindi, nel sorgente che da' errore, devi mettere all'inizio
	#include <errno.h>
Questo cura d'un botto ENOMEM, EINVAL, EPERM, E 'STI... :-)))
A questo punto, mi pongo pero' la domanda, come mai il configure non si
e' accorto che mancava l'inclusione di "errno"? E sospetto che tu abbia
messo qualche parametro losco o imprevisto in fase di configurazione.
Leonardo
-- 
Nach doiligh domhsa mo chailin a mholadh
'S ni he amhain mar bhi si or
Bhi si mar gath greine a dhul in eadan na gloinne
Is bhi sceimh mhna na finne le mo cailin or

 uscito".
In sintesi: esci con un codice indefinito :)
L'unica certezza che hai e' che quando e' stato restituito quel valore era 
un const char*.
Il puntatore potrebbe anche essere rimasto vivo (valido) al ritorno della 
funzione: mi aspetterei qusto comportamento se la funzione restituisse un 
const char* (anche se e' possibile che gli estensori dello standard la 
pensassero diversamente) ed e' probabile che il compilatore passi 
direttamente il valore della posizione della stringa nel segmento dati del 
programma, anziche' copiarla nello stack; questo che renderebbe il puntatore 
a tutti gli effetti una costante nel corso della stessa esecuzione... 
Comunque, nulla garantisce che sia effettivamente cosi', ne' che tra due 
diverse esecuzioni il valore del puntatore non cambi.
Vivo o morto che sia il puntatore, sicuramente non e' un int (typecast o 
meno), e sicuramente il suo valore come intero e' ignoto; inoltre anche se 
il confronto fosse fatto tra 'return "ENOMEM";' e 'if (x == "ENOMEM")', il 
risultato sarebbe falso (salvo il caso estremamente improbabile che il 
compilatore si legga tutti i const char* e raggruppi quelli di contenuto 
uguale per risparmiare spazio nel compilato, "ENOMEM" e' un array diverso 
nei due casi).
Ora, il *comportamento* puo' non essere indefinito (cioe', il compilatore 
puo' anche avere precise istruzioni, da standard, su cosa fare quando 
incontra questa situazione), ma sicuramente il *valore* ritornato e' 
indefinito.


 un const char*.
ripeto, no.  su questa piattaforma un const char * e' di 64 bits, ed
un intero di 16; la conversione trasforma il pointer in qualcosa di
assolutamente schifido.


 assolutamente schifido.
E allora non hai manco quella certezza...  P
Ma l'intero non dovrebbe essere di 32 bit? Non che cambi nula, visto che 
tronca comunque un puntatore a meta' lunghezza. Devo stare piu' attenzione 
col sizeof quando scrivo codice... Non che ne scriva tanto ormai.


Per rispondere a tutti apro un altro thread.
Allora, come suggerito sia da Maurizio Loreti che Leonardo Serni Alessandro
e tutti gli altri, mi manca una qualche libreria che definisce ENOMEM e
altre cose che cominciano per E .
Lanciando il comando "./configure" non viene rilevato alcun errore.
Lanciando il comando "grep -ri ENOMEM /usr/include/*" ottengo (metto solo il
nome dei files):
/usr/include/SDL/SDL_error.h:
/usr/include/aal/types.h:#undef ENOMEM
/usr/include/apr-0/apr_buckets.h: *         APR_ENOMEM if allocation failed;
/usr/include/apr-0/apr_errno.h:/** @see APR_STATUS_IS_ENOMEM */        
/usr/include/argz.h:   ENOMEM is returned, otherwise 0.  The result can
/usr/include/asm-mips/sgiarcs.h:#define PROM_ENOMEM                     0x10
/usr/include/asm-s390/idals.h:                  return -ENOMEM;
/usr/include/asm-sparc/solerrno.h:#define       SOL_ENOMEM         12    /* 
/usr/include/asm-sparc/bsderrno.h:#define BSD_ENOMEM        12     /* Cannot 
/usr/include/asm-sparc64/solerrno.h:#define     SOL_ENOMEM         12    /* 
/usr/include/asm-sparc64/bsderrno.h:#define BSD_ENOMEM        12     /* 
file /usr/include/c++/3.4.4/x86_64-slackware-linux/bits/stdc++.h.gch/O0g
matches Binary
file /usr/include/c++/3.4.4/x86_64-slackware-linux/bits/stdc++.h.gch/O2g
matches
/usr/include/gcrypt.h:    err = ENOMEM;                                                       
/usr/include/glib-2.0/glib/gspawn.h:  G_SPAWN_ERROR_NOMEM,       
/usr/include/gpg-error.h:    GPG_ERR_ENOMEM = GPG_ERR_SYSTEM_ERROR | 86,
/usr/include/libsmbclient.h: *                  - ENOMEM Out of memory
/usr/include/libsmbclient.h: *    
/usr/include/libxml2/libxml/xmlerror.h:    XML_IO_ENOMEM, /* 
/usr/include/linux/fs.h: *    %ENOMEM).
/usr/include/linux/i2o.h: *     Returns 0 on success or -ENOMEM on failure.
/usr/include/linux/ipmi.h: *   - ENOMEM - Buffers could not be allocated for 
/usr/include/linux/ipmi.h: *   - ENOMEM - Buffers could not be 
/usr/include/linux/kthread.h: * Returns a task_struct or ERR_PTR(-ENOMEM).
/usr/include/linux/libata.h:    return (ap->pad == NULL) ? -ENOMEM : 0;
/usr/include/linux/security.h: *                -ENOMEM on memory allocation 
/usr/include/linux/skbuff.h: *  If there is no free memory -ENOMEM is ret
/usr/include/linux/sunrpc/svc.h:                return -ENOMEM;
/usr/include/linux/textsearch.h:                return ERR_PTR(-ENOMEM);
Come vedete la libreria errno.h non c'e', eppure ho compilato parecchi
programmi, e nessun configure si e' mai lamentato, e il kernel lho
scaricato da internet (
kernel.org
) e compilato, poi ho
linkato /usr/include/linux -> /usr/src/linux/include/ .
-- 
Jacquin's Postulate on Democratic Government:
 No man's life, liberty, or property are safe while the
legislature is in session.

 cominciano per E .
non una libreria, ma un header.
,-----
| MLO@mlinux 12 $ cat foo.c
| #include <stdio.h>
| #include <errno.h>
| int main() { printf("ENOMEM = %d\n", ENOMEM); return 0; }
| MLO@mlinux 13 $ gcc -std=c99 -pedantic -W -Wall -o foo foo.c && ./foo
| ENOMEM = 12
| MLO@mlinux 14 $ gcc --version
| gcc (GCC) 4.0.2
| Copyright (C) 2005 Free Software Foundation, Inc.
| This is free software; see the source for copying conditions.  There is NO
| warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| MLO@mlinux 15 $
`-----
<errno.h> è standard per il C fin dai tempi del primo K&R; se non ce
l'hai, hai una versione bacata del compilatore.
