1

これには gcc で Netbeans を使用していますが、呼び出し元の関数と呼び出された関数の間で関数の引数の値が壊れていることがわかりました。

myfuns.h で:

float dotprod( float u1, float u2, float u3,  float v1, float v2, float v3 );

myfuns.c で

 float dotprod( float u1, float u2, float u3, float v1, float v2, float v3 )
 {
    float res= u1*v1+u2*v2+u3*v3 ;
    return res;
 }

main.c で

 ...
 float dp=dotprod( rx, ry, rz,  ddx, ddy, ddz );
 ...

dotprod() 関数で u1、u2 などの値を出力したり、デバッガーでそれらを調べたりすると、その値は main.c の rx、ry などの値とは異なります

引数を float から float* に変換すると、問題は解決したようです。また、6 つの float 引数の前後にダミーの整数引数を追加しようとしました。最初の引数は問題ありませんが、最後の引数も破損します。エラーを見つけるのに何時間も費やしました。

助言がありますか ?

4

2 に答える 2

1
  1. これらすべての変数の型はmain()として指定されていfloatますか?
  2. 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)

この特定のケースでは、 myintfloattype は同じ幅 (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
于 2012-10-09T06:23:35.367 に答える
0

関数パラメーターで同じタイプのデータを渡していることを確認してください。つまり、サイズと表現です。

非常に単純なテストの場合、メインでこれを試してください:

float dp=dotprod( (float)rx, (float)ry, (float)rz,  (float)ddx, (float)ddy, (float)ddz );
于 2012-10-09T06:38:48.253 に答える