argv, environ och NULL

Här pratar vi programmering i dessa olika former. Perl, C/C++, Pascal, ADA, Lisp, COBOL, ZX Basic och mm.
Post Reply
erik_persson
Posts: 1474
Joined: 29 August 2002, 15:19

argv, environ och NULL

Post by erik_persson » 25 April 2010, 15:35

environ, eg char **environ, är ju NULL-terminerad, dvs den sista strängen som environ pekar på är NULL.
Annorlunda uttryckt så är den sista strängen som environ pekar på en tom sträng. Denna tomma sträng tjänstgör som slutmarkör för environ.
(Jag pratar alltså här INTE om det triviala att varje c-sträng är null-terminerad.)

Det behövs således inte någon storleksangivelse för environ utan tex:

for (int i = 0; environ; ++i) { printf("%s\n", environ); }

fungerar (C99-style där det är ok att deklarera och definiera variabler i for-loopen).


Klassiskt så fås kommandoradsparametrar via:
int main(int argc, char *argv[]) { ... }

Antalet argument anges i argc.

Av en ren händelse så noterade jag att också argv är NULL-terminerad på samma sätt som environ.
Det är av mindre betydelse eftersom antalet argument anges av argc, men jag har inte sett att detta är standardiserat trots en del c- och c++-programmering.
Nu undrar jag helt enkelt om det är så att argv enligt standard ska vara NULL-terminerad på samma sätt som environ?
(Jag antar att det inte är så eftersom jag inte stött på detta tidigare, men det finns säkert någon här som vet det bättre!)

/erik

erik_persson
Posts: 1474
Joined: 29 August 2002, 15:19

Re: argv, environ och NULL

Post by erik_persson » 26 April 2010, 15:04

erik_persson wrote:environ, eg char **environ, är ju NULL-terminerad, dvs den sista strängen som environ pekar på är NULL.
Annorlunda uttryckt så är den sista strängen som environ pekar på en tom sträng. Denna tomma sträng tjänstgör som slutmarkör för environ.
(Jag pratar alltså här INTE om det triviala att varje c-sträng är null-terminerad.)

Det behövs således inte någon storleksangivelse för environ utan tex:

for (int i = 0; environ; ++i) { printf("%s\n", environ); }

fungerar (C99-style där det är ok att deklarera och definiera variabler i for-loopen).


Klassiskt så fås kommandoradsparametrar via:
int main(int argc, char *argv[]) { ... }

Antalet argument anges i argc.

Av en ren händelse så noterade jag att också argv är NULL-terminerad på samma sätt som environ.
Det är av mindre betydelse eftersom antalet argument anges av argc, men jag har inte sett att detta är standardiserat trots en del c- och c++-programmering.
Nu undrar jag helt enkelt om det är så att argv enligt standard ska vara NULL-terminerad på samma sätt som environ?
(Jag antar att det inte är så eftersom jag inte stött på detta tidigare, men det finns säkert någon här som vet det bättre!)

/erik


exec-funktionerna tar arrayer av strängar, där arrayerna måste termineras med NULL.
Det är förmodligen detta som ses.

/ep

Fader_Berg
Posts: 180
Joined: 2 September 2009, 09:31

Re: argv, environ och NULL

Post by Fader_Berg » 27 April 2010, 11:10

I fallet argv så är det kanske inte en C-fråga direkt... Det borde väl avgöras utav OS:et, hur den trycker upp stacken innan programmet startar.

erik_persson
Posts: 1474
Joined: 29 August 2002, 15:19

Re: argv, environ och NULL

Post by erik_persson » 27 April 2010, 18:16

C är standardiserat där utseende av många funktioner och strukturer är definierat och inte minst finns därtill tex POSIX, och det är just detta som jag är intresserad av.

I viss mån är alla bibliotek implementationsberoende, men vissa bibliotek skall finnas och måste ha vissa funktioner som ska ha ett viss utseende och ett visst beteende för att den aktuella C-implementationen ska uppfylla tex C99.
Därtill finns andra standarder som POSIX.

För exec-anropen så måste tex *argv[]-pekaren termineras med en pekar till NULL i såväl linux som bsd, och är specificerad att ha detta utseende enligt POSIX, dvs argv[]-pekaren SKALL terminaras med null i dessa systemanrop.

Den intressanta frågan är om detta fortlever även i main(int argc, char *argv[]), men det är svårare att hitta.

Här kan det ju mycket väl vara så att just detta *inte* är standardiserat och att operativsystemet är fritt att hitta på bus med argv-pekaren, men det är just precis det som jag är intresserad av att veta.

/erikp

Fader_Berg
Posts: 180
Joined: 2 September 2009, 09:31

Re: argv, environ och NULL

Post by Fader_Berg » 28 April 2010, 11:50

Jag tror inte det finns någon standard på hur alla operativsystem ska leverera argument till program, annat än den vi ser bokstavligen i just main(int argc, char* argv[]), (om man nu vill följa C-standarden när man utveklar OS:et). Har POSIX det som standard så kan man ju räkna med att POSIX kompatibla OS gör så. Men det är ju inte givet att andra gör så, även om det är högst troligt.

Att exec-anropen avslutas med null, skulle ju kunna vara resultat av ett programmeringssätt snarare än en standard hur leverera argument till ett systemanrop, (även om jag inte tror att så är fallet för POSIX). Jag använder hellre null som avgränsare i funktioners argument t.ex., än en extra integer-variabel för att förmedla längden på en array.

erik_persson
Posts: 1474
Joined: 29 August 2002, 15:19

Re: argv, environ och NULL

Post by erik_persson » 28 April 2010, 20:00

Fader_Berg wrote:Jag tror inte det finns någon standard på hur alla operativsystem ska leverera argument till program, annat än den vi ser bokstavligen i just main(int argc, char* argv[]), (om man nu vill följa C-standarden när man utveklar OS:et). Har POSIX det som standard så kan man ju räkna med att POSIX kompatibla OS gör så. Men det är ju inte givet att andra gör så, även om det är högst troligt.

Att exec-anropen avslutas med null, skulle ju kunna vara resultat av ett programmeringssätt snarare än en standard hur leverera argument till ett systemanrop, (även om jag inte tror att så är fallet för POSIX). Jag använder hellre null som avgränsare i funktioners argument t.ex., än en extra integer-variabel för att förmedla längden på en array.
Nu har jag kontrollerat hur det är. Enligt C-standarden SKA argv i main avslutas med en pekare till NULL, dvs argv[argc] SKA vara NULL.
Det gör att argc i main i *viss* mån skulle kunna betraktas som överflödig (nu är det iofs inte så), men att ha en variabel som anger storleken av en array är definitivt behändigt (för att man slipper beräkna storleken och för att null-metoden inte är tillämplig annat än för arrayer av pekare och inte ens alltid där).

Orsaken att jag tog upp exec var enbart för att det överensstämde med vad jag sett för argv i main, och att det blir enkelt för exec att hantera argumenten så att argv[argc] är null i main. När det nu visar sig att argv[argc] i main ska vara NULL så blir det naturligtvis helt självklart att exec-varianterna också ska avslutas med en pekare till NULL.

Fader_Berg
Posts: 180
Joined: 2 September 2009, 09:31

Re: argv, environ och NULL

Post by Fader_Berg » 28 April 2010, 20:37

Se där... ja då vet vi.
men att ha en variabel som anger storleken av en array är definitivt behändigt (för att man slipper beräkna storleken och för att null-metoden inte är tillämplig annat än för arrayer av pekare och inte ens alltid där)
Jag tycker det är onödigt många gånger och det funkar alldeles ypperligt för mig.

Post Reply