-2

MinGW 4.6.2 の場合 (sourceforge では 4.7.x が「最新」ではないため、これをインストールしました)

void test(int *in)
{
    *in = 0;
}
int main()
{
    int dat;
    test(dat);
    return dat;
}

おそらくご存知のように、これにより ac プロジェクトで警告が表示されます。

dirpath\fileName.c|8|warning: passing argument 1 of 'test' makes pointer from integer without a cast [enabled by default]

また、C++ プロジェクトで 2 つのエラーが発生しました。

dirpath\fileName.cpp|8|error: invalid conversion from 'int' to 'int*' [-fpermissive]|

dirpath\fileName.cpp|1|error: initializing argument 1 of 'void test(int*)' [-fpermissive]|

私の質問は、次の2つのシナリオで(メモリ内で)正確に何が起こるかです-fpermissive.acプログラムとして有効またはコンパイルされていると仮定します。

  1. datは初期化されておらず、プログラムが続行されます (セグメンテーション違反は発生しません)。
  2. datは 42 に初期化され、プログラムは続行します (そしてセグ フォールトを行います)。

datケース 2 ではセグ フォールトが発生するのに (おそらくメモリ ロケーションに値を割り当てようとして)、初期化されていないままにしておくとセグ フォールトが発生しないのはなぜですか(おそらく偶然ですか?)。

好奇心:フラグの意味fは何ですか? -fpermissive(冗長なようです)

4

3 に答える 3

3

プログラムは未定義の動作をそのまま持っているので、その動作を推論しようとするのは無意味ですが、とにかく...

関数は へのtest()ポインタを期待していますint。そのポインターは逆参照され、intit が指す先を設定するために使用されます。ただし、ポインターを渡すのではintなく、初期化されていないintため、その変数にあるガベージ値をメモリアドレスとして解釈し、その背後にあるオブジェクトにアクセスしようとします。

関数を正しく呼び出したい場合は、次のように書く必要があります

test(&dat);

代わりは。

-fpermissiveフラグの f は何を表しているのでしょうか?

いいえ、私の知る限り、それは「機能」の略です。(しかし、の場合は、「このフラグを使用する-fpermissiveと、コードが失敗する」という意味だと思います... )

于 2013-07-26T04:45:17.947 に答える
2

警告が言うようpassing argument 1 of 'test' makes pointer from integerに、渡された整数の値であるアドレスから何かを取得しようとしています。それは何でもかまいません。

値42を渡すと、コンパイラーはユーザー用に予約されていないアドレスで値を取得することを余儀なくされ、42Segfaultを取得しています。デフォルトでは、コンパイラーはいくつかの値を割り当てており、後でこの値がアドレスになり、どういうわけか幸運ですこれでセグメント違反は発生しません。

于 2013-07-26T04:49:33.200 に答える
1

c では、デフォルトで値渡しが行われます。

void test(int *in)
{
   *in = 0;
}

test(dat); // passing value

ここでは、初期化されていないデータを渡しています。ガベージ値を考慮します。したがって、ガベージ値をテスト関数のメモリアドレスとして機能させようとしています。これは未定義の動作です。代わりに、これを試すことができます。

test(&data);

あなたの質問に来ます。

Q. dat is uninitialized and the program proceeds (and no segmentation fault occurs).
A. This is an undefined behaviour because your are passing a garbage value. If your
   garbage value is a proper memory address then it will not cause segmentation error.
   If it is not proper, it will cause segmentaion error. So it happend at runtime 
   dynamically and can give either segmentation fault or can run.  

Q. dat is initialized to 42, and the program proceeds (and does seg-fault)
A. Here you have initialized dat to 42. By default c works on pass by value definition.
   So you are passing 42 to test. test will consider 42 as a memory location, which 
   is not a proper memory location so it cause segmentation error.
于 2013-07-26T06:08:45.097 に答える