少しググッてみたけど答えは見つからなかった。とにかくmain()に渡されるargcとargv。これを引数で渡すことナシに別の関数から勝手に参照したいと思い立った。
なんでそんなことをしたくなったのか分からない。でも思い立ったものはしょうがない。
それなりに調べていくと、環境変数を示すenvironというグローバル変数を使えば良いようだ。
extern char **environ;
そしてenvironとargc/argvは以下のような関係にあるらしい。
- (long)environ[-2-argc] = argc
- environ[-2-(argc-1)] = argv[0] (= 実行ファイルを示す文字列)
- environ[-2-(argc-2)] = argv[1] (= 第1引数)
- :
- environ[-2] = argv[argc-1]
- environ[-1] = argv[argc] (= NULL)
- environ[0] = ここから環境変数
- :
とても移植性があるとは思えないですね。Linuxでは動作したが。
#include <stdio.h> void show_argv(){ extern char **environ; int n=-1; if(environ[n]!=NULL) return; --n; while((long)(environ[n])!=-n-2){ --n; } int argc=(long)(environ[n]); char **argv=&environ[n+1]; int i; for(i=0; i<argc; ++i){ printf("%d: %s\n", i, argv[i]); } } int main(int argc, char **argv){ printf("in-main\n"); int i; for(i=0; i<argc; ++i){ printf("%d: %s\n", i, argv[i]); } printf("out-main\n"); show_argv(); return 0; } // gcc -Wall -o test-argv test-argv.c
以下、実行結果。
# ./test-argv test argument here. in-main 0: ./test-argv 1: test 2: argument 3: here. out-main 0: ./test-argv 1: test 2: argument 3: here.
でも、移植性のある方法はないんでしょうかね?