お世話になっております。閃人です。
ネットで色々調べてみたのですが、解決できなかったため、教えていただけますでしょうか。
VC++ 6.0 + WinXP環境です。
static void StaticFunc( int n ) {
int j;
};
上記のような関数があったとします。
複数のスレッドからこの関数が呼ばれた場合、
静的メンバ関数の引数や、関数内で定義したAuto変数は書き換わらないのでしょうか?
私の認識では、上書きされてしまう為、排他制御が必要と思っていました。
サンプルアプリを作ってテストしてみたところ、
引数のアドレスもAuto変数のアドレスも違うところを指しており、
各スレッドで上書きされることがありませんでした。
関数のアドレスは一緒でも、別レジスタを取ったりするのでしょうか?
この辺に詳しい方、教えていただけないでしょうか。
以上
宜しくお願い致します。
特に詳しいわけではありませんが、一つだけ。
関数内の変数を共有させちゃったら再帰関数を実現できませんよね?
> 関数内の変数を共有させちゃったら再帰関数を実現できませんよね?
確かにそうですね。盲点でした。
ありがとうございます。
他に、何か情報がありますでしょうか。
> 他に、何か情報がありますでしょうか。
上記のように書きましたが、keichanさんに教えて頂いた内容で、全てがなっとくいきますので、この問題はFIXさせて頂きます。
ありがとうございました。
私もがんばって、皆さんの質問に答えられるようになりたいと思います。
言っていることが今一理解できてないのですが、
掲示のソースコードではstaticに宣言されたのは関数の本体のみ
ですよね(確認)。従って、この関数の本体はアプリケーション内で
唯一の実体となります。関数の本体とは関数のアドレスのことです。
ですが、この関数の引数や関数内の「staticでない」変数はスタック上
に確保されるため、そのときのコール元のSPレジスタの値に依存して
「常に」異なります。
引数とauto変数は利用されるときにSPレジスタに依存したアドレスに、
利用される直前に確保され、そのスコープを抜けたら既に無効と考え
なければなりません。
>static void StaticFunc( int n ) {
> int j;
>};
これは静的メンバ関数ではなくファイルスコープの非メンバー関数だと思われるが
えー、どの辺が知りたいのかで話の内容が変わってくるのだが、とりあえず知っておくべきは
・静的変数(静的メンバ変数+関数内静的変数+大域変数)は共有される
・関数内自動変数や関数の引数は共有されない
ように *コンパイラやリンカやOS自体を実装しなければならない* ということ。
逆に言えば VC++ に限らず一般的に実用されている処理系は、そのように実装されているので問題ない、ということ。
> 関数のアドレスは一緒でも、別レジスタを取ったりするのでしょうか?
これは、そのように実装するための *詳細仕様* なわけだ。
実装詳細を論じるには VC++ や gcc などの内部に指突っ込む必要がある。
一般プログラマとしてはそういう詳細は知らなくてもいい。
問題なく排他処理なしに使えること、だけ知っていれば十分。
自動変数そのもの、引数そのものには排他処理は不必要なんだけど
それがポインタであるとしたら、その指す先には排他処理が必要かもしれない。
それはまた別の話だったりするわけだけどさ
To 仲澤@失業者さま
内容の薄い質問をしてしまい、申し訳ありません。
くみ取って頂き、的確な回答をありがとうございます。
大変勉強になりました。
To tetrapodさま
例が適当で申し訳ありません。
極力シンプルにしようと思ったのですが、適当過ぎました。
大変わかりやすい回答をありがとうございます。
にわかじこみのプログラマを脱退できるよう精進します。