Newsgroup: it.comp.os.linux.development
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

 
perchè setenv non è dichiarata quindi, se stai programmando in C, il 
compilatore assume che la dichiarazione implicita della funzione sia:
int setenv();
ma ne esiste comunque l'implementazione (da qualche parte nelle librerie 
che includi).
-- 
... dimostrando che o non aveva capito di cosa si stava parlando o per 
qualche astruso motivo ce l'aveva con me e ne ha approfittato per 
sfoderare la sua spada. ...



A me e' successo molte volte, e (mi associo) non ho mai capito
perche'.  Mi associo anche al consiglio di fregartene e di usare il
programma nonostante il warning (che e' solo un warning, dopotutto).
Pero' vorrei sottolineare una cosa: compilando
#include <stdio.h>
#include <stdlib.h>
int main() {
  int i = setenv("FOO", "bar", 1);
  printf("%d\n", i);
  return 0;
}
(anche con -D__USE_BSD) il warning viene scritto; ma compilando con
g++ (e notoriamente il C++ e' moooolto piu' schizzinoso del C su certe
cosucce) il warning sparisce.  Qualche frequentatore del NG ha la
spiegazione?
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy              ROT13: 
ybe...@cq.vasa.vg

 perche'. 
-ansi oppure -std=c99?
Luca
-- 
Home: 
http://kronoz.cjb.net
La vasca da bagno fu inventata nel 1850, il telefono nel 1875.
Se fossi vissuto nel 1850, avrei potuto restare in vasca per 25 anni
senza sentir squillare il telefono

 -ansi oppure -std=c99?
La risposta e' arrivata su gnu.gcc.help, dove ho sottoposto la stessa
domanda, da uno dei developers di gcc.  Eccola:
| > Consider this snippet: [...]
| > Also compiling with -D__USE_BSD gives the same warning.
| >
| > Question 1: why gcc complains, if setenv is correctly prototyped?
| 
| Because it isn't. Run "gcc -ansi -dD -D__USE_BSD foo.c > foo.i"
| and examine the result. You'll find that setenv() is *not*
| prototyped.
| 
| You'll also find:
|   # 99 "/usr/include/features.h" 3 4
|   #undef __USE_BSD
| 
| If you want to have __USE_BSD in effect, you should have
| -D_BSD_SOURCE on command line.
| 
| > Question 2: since C++ is more picky than C about these issues, why g++
| >             does not complain?
| 
| Because 'g++' silently adds -D_GNU_SOURCE (which 'gcc' doesn't),
| and in stdlib.h we find:
| 
|   /* If _GNU_SOURCE was defined by the user, turn on all the other features.  */
|   ...
|   # define _BSD_SOURCE    1
| 
| Cheers, Pavel Pluzhnikov


 | 
 > [snip spiegazione]
e si sa anche il perchè (mera curiosità)?


 e si sa anche il perchè (mera curiosità)?
Il perché è spiegato nella risposta di Maurizio.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 
intendevo: perchè setenv non è dichiarato in <stdlib.h> per il gcc ma lo 
è per il g++? ho capito che per il secondo viene definita implicitamente 
la macro _GNU_SOURCE, quello che mi sfugge è perchè non si fa in modo 
che sia dichiarata in <stdlib.h> per entrambi i compilatori.


 e si sa anche il perchè (mera curiosità)?
Si.  In sostanza, il contenuto di <stdlib.h> e' dettato dallo Standard
(aka ISO/IEC 9899-1999); ma alcuni ambienti, in questo caso BSD, hanno
ficcato dentro stdlib.h anche i prototipi di procedure come setenv; se
guardi in fondo a "man setenv", infatti, trovi scritto 'Conforming to:
BSD 4.3'.
Se tu richiedi stretta osservanza dello Standard (-ansi, oppure
-std=c99 o -std=c89) gcc (correttamente, secondo me) cancella da
<stdlib.h> ogni riferimento a procedure non implementate dallo
Standard stesso.
Quello che non mi torna e' che, usando g++, tutto vada a posto;
secondo logica, richiedendo stretta osservanza dello Standard, il
warning ci vuole anche li'.  E mi da' un po' fastidio che direttive
per il preprocessore come -D_BSD_SOURCE e -D_GNU_SOURCE non siano
descritte in "info gcc" ne' nei manuali cartacei "Using the GNU
Compiler Collection" e "The GNU Compiler Collection internals"; ma
solo all'inizio del manuale della glibc, un bel mattone di 1078 pagine
:-)
And now, for something completely different ((C) monty Python):
qualche appassionato di Sudoku nei pressi cui interessi il mio
software?  
http://wwwcdf.pd.infn.it/MLO/sudoku.tar.gz
 ...
