- これらすべての変数の型は
main()
として指定されていfloat
ますか?
dotprod()
呼び出したときに表示されるプロトタイプはありますか? つまり、メイン ファイルには#include "myfuns.h"
?
特に、その 2 番目の質問に「いいえ」と答えると、コンパイラーは、渡される引数について特定の仮定を行い、値を異なる幅にするか、異なる方法で解釈することを意味します。
たとえば、次のことを考慮してください。
#include <stdio.h>
int main(int argc, char *argv[]) {
float x = 1.5, y = 2.5;
fn (x, y); // <-- compiler makes assumptions.
return 0;
}
void fn (float a, float b) { // <-- compiler should complain
printf ("%f %f\n", a, b); // about bad assumptions.
}
出力:
0.000000 1.937500
それは本当にあなたが期待するものではありません。これは gcc でコンパイルされており、吐き出された多数の警告は、戻ってコードをチェックするのに十分な理由であったはずです(a)。
この特定のケースでは、 myint
とfloat
type は同じ幅 (32 ビット) ですが、コンパイラは関数が を受け入れると考えるため、int
最初にこれらの float をその型に変換します。残念ながら、関数がスタック上のこれらの値を調べると、まったく異なる方法でエンコードされた型int
として解釈します。float
予想される型と実際の型の幅が異なる場合は、スタックに置かれたデータよりも多くのデータを使用しようとする可能性があるため、さらに悪化する可能性があります。
この特定のコード サンプルは、以下を挿入するだけで修正できます。
void fn (float, float);
プロトタイプが想定されないように、前にmain()
(または交換main()
して前後に)。fn()
これにより、gcc からの警告がなくなり、正しい出力が得られます。
1.500000 2.500000
基本的に、呼び出し元と呼び出し先が渡されたパラメーターに同意することを確認する必要があります。これには、呼び出し規約、データ型、パラメーター数などが含まれます。これらのいずれかに不一致があると、問題が発生します。
(a):私のシステムでは、次のようになります。
testprog.c: In function ‘main’:
testprog.c:5: warning: implicit declaration of function ‘fn’
testprog.c: At top level:
testprog.c:9: warning: conflicting types for ‘fn’
testprog.c:5: note: previous implicit declaration of ‘fn’ was here