Newsgroup: it.comp.lang.c
Titolo: Warning utilizzando "setenv()" pur includendo stdlib.h

Ciao a tutti, sto cercando di settare in un programma C sotto Linux una 
directory corrente a mia scelta solo che quando vado ad utilizzare in 
questo modo:
__________________________
switch( cs ){
      case RADICE:
        if(  chdir("/")<0  )
	 printf("error accessing directory: %s\n", *((cmd1->argvcmd)+1));
        else if( setenv("PWD","/",1)==0 );
	 else
	   printf("error accessing directory: %s\n", *((cmd1->argvcmd)+1));
        break;
   }
----------------------------
la funzione setenv() ottengo in fase di compilazione:
"warning: implicit declaration of function `setenv'"
nonostante io abbia correttamente incluso <stdlib.h>. Ecco infatti le 
mie include:
_________________
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-----------------
Nel mio stdlib.h (headers in dotazione con mdk10.1) setenv è dichiarata 
in questo modo:
__________________
#if defined __USE_BSD || defined __USE_XOPEN2K
/* Set NAME to VALUE in the environment.
    If REPLACE is nonzero, overwrite an existing value.  */
extern int setenv (__const char *__name, __const char *__value, int 
__replace)
      __THROW;
------------------
Come posso fare per non avere questo warning?
Come mai il programma funziona correttamente e setenv() opera 
correttamente nonostante questo warning?
	ciao e grazie, rz
-- 
http://mrzac.altervista.org

 mie include:
Appunto...il warning ti avverte che è già implicita la 
dichiarazione...quindi togliendo stdlib.h, non dovrebbe più
dartelo...


Ma sulla mia documentazione leggo che setenv() richiede stdlib.h per 
essere usata... la sua dichiarazione è implicita in che senso?
Quindi se uso nel mio programma funzioni di stdlib.h posso ignorare il 
warning non potendo togliere tale header file nelle include?


 warning non potendo togliere tale header file nelle include?
Il fatto è che mentre in win le librerie standard devono per forza 
essere incluse, in linux le librerie standard sono implicitamente 
incluse nel compilato...questo perchè il gcc o g++ linkano 
automaticamente la libc (che contiene le funzioni standard...)

 dartelo...
Non è così.  L'"implicit declaration" è la deduzione che fa il
compilatore, dovuta al fatto che non trova il prototipo.  L'inclusione del
file header serve a fargli trovare il prototipo (di conseguenza il warning
non verrebbe fuori).
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 non verrebbe fuori).
Ok, ma includendo il file header che gli da questo messaggio...!

 Ok, ma includendo il file header che gli da questo messaggio...!
Che vuol dire ?


 ha scritto:

No, il messaggio e` ortogonale all'inclusione dell'header. Quel
messaggio significa che il compilatore non ha in prototipo della
funzione e quindi lo deduce (i.e. tira ad indovinare) in base all'uso
che ne viene fatto.
Se il protipo fosse visibile il compilatore non darebbe alcun warning.
Il prototipo e` effettivamente in stdlib.h, ma l'OP sta probabilmente
usando l'opzioni -std=c99 (oppure -ansi) del gcc che impedisce (tramite
#ifdef) la dichiarazione di quella funzione (che non e` standard ISO).
Luca
-- 
Home: 
http://kronoz.cjb.net
Se non sei parte della soluzione, allora sei parte del problema.

 Che vuol dire ?
Scusate...o non so leggere io, o voi!!!
Lui ottiene quel warning nonostante abbia già incluso
l'header stdlib.h!!!

 l'header stdlib.h!!!
La funzione che l'OP sta usando è BSD, non standard ISO.
Includere stdlib.h, quindi, è sicuramente necessario, ma forse non
sufficiente.  Se, pur includendo il file header, si continua ad avere il
warning è perché il preprocessore sta saltando il prototipo.  L'unico
motivo per cui salti il prototipo è che nessuna delle due "define" sia
definita.
Il motivo per cui le define non sono definite è che il compilatore stia
presumibilmente compilando in una modalità non compatibile con BSD.


 
Grazie a tutti per le risposte.
Come si deve procedere in questi casi (ci si accorge che non si può fare
a meno di uscire dallo standard ansi) durante la realizzazione di un
programma C? Sono un principiante del C e fino ad ora mi limitavo a
compilare in ansi C.
Preso atto che il programma non è più ansi C, si deve andare a ricercare
nel file header che definisce la funzione in esame e definire una o più
macro in base alle istruzioni del file header o ci si limita ad
informarsi su quale flag passare al compilatore (uso gcc sotto linux)?
In questo caso come dovrei agire? Compilavo con il flag -ansi attivato. 
Togliendolo il warning scompare...
Tolgo semplicemente il flag -ansi, lo lascio ma aggiungo una macro che 
va a includere la dichiarazione della funzione in esame, aggiungo un 
altro flag che allarga lo standard a cui aderisce il mio programma o 
sostituisco il flag -ansi con un altro che includa la funzione di cui ho 
bisogno e tutte le altre usate (in questo caso il codice anzichè essere 
ansi C seguirebbe lo standard che non mi dà warning)?
	ciao, rz
-- 
http://mrzac.altervista.org

 ansi C seguirebbe lo standard che non mi dà warning)?
Stai delirando ;-)... limitati a non usare il flag -ansi.



Il compilatore e` gia` predisposto con i flag corretti per utilizzare la 
libreria.  E anche se non esplicitamente diretto usa lo standard ansi 
per l'analisi e la validazione del codice.  Aggiungere la flag -ansi 
limita l'uso a solo quelle funzioni definite dallo standard ANSI/ISO. 
Francamente io credo che sia quasi impossibile fare programmi con solo 
quelle librerie.
Io ti suggerisco di aggiungere -Wall fra le opzioni. Potresti trovare 
qualche segnalazione interessante.


 
Intendevo dire: si usa allargare l'insieme (termine inteso in senso 
matematico) dello standard del proprio sorgente mettendo più flags tipo 
"-ansi" e contemporaneamente "-BSD" o non produce niente di buono perchè 
non possono coesistere? O mettendo "-BSD" ottengo già tutte le funzioni 
dello standard ansi definite nelle librerie PIU' quelle BSD?
Penso che mi basterebbero quelle BSD + quelle posix...


 non possono coesistere?
Scrivere -ansi significa impostare la compatibilità C89 (equivale a -std=c89
o -std=iso9899:1990).
-BSD non mi sembra sia un'opzione valida.
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 -BSD non mi sembra sia un'opzione valida.
Per fare quello che chiedi, devi passare -D_BSD_SOURCE che definisce la
macro _BSD_SOURCE e fa includere tutti i prototipi BSD. Se, piu` in
generale, vuoi poter usare tutto quello che sta nella Single Unix
Specification, oltre al parametro di cui sopra, passi -D_XOPEN_SOURCE e
-D_SVID_SOURCE. Non mi pare che serva altro.
Saluti,
Marco
-- 
To email me, remove the no_ and _spam from my address.

 Marco



Molto piu` semplicemente non basta usare il default?  Cioe` senza la 
flag -ansi?


 -ansi?
Se hai la certezza che il tuo codice sara` compilato sempre col Gcc (o
compatibile) allora si`, ma visto che di default il Gcc usa -gnu89, che e`
l'ANSI C + le estensioni Gnu, se non sei sicuro che il codice sara`
compilato con il Gcc allora devi affidarti all'ANSI C e alla Single Unix
Specification.
Ovviamente tutto dipende dai singoli casi. Io per esempio
uso -c99 come opzione del Gcc, ma in questo modo perdo la maggior
parte dei prototipi Unix previsti dalla SUSv3, allora con le tre
opzioni che ho suggerito mi assicuro che ci siano tutti.
