2016-12-08 5 views
1

私は突然gcc 6の下で警告を出すC++のFortranルーチンを呼び出す科学計算コードを使用します。 。ここでは必要最小限の問題である:C++のstd :: complexとcomplex :: 16の間の型不一致gcc 6の下でリンク時の最適化

mult.f90で定義されたFortranのサブルーチンmultを考えてみましょう:

subroutine mult(c) 
    complex*16 c 
    c = c * c 
    return 
end 

私はC++ファイルtest.cppからこれを呼び出す:

#include <complex> 
#include <iostream> 

extern "C" void mult_(std::complex<double> *); 

int main() { 
    std::complex<double> z (1,0); 
    mult_(&z); 

    std::cout << z << "\n"; 
    return 0; 
} 

私はG ++使用してファイルをコンパイルするとき - 6を、私は次の警告を得る:私は、次のいずれかを行う場合

$ g++-6 -O3 -W -Wall test.cpp mult.f90 -flto -o test2 

test.cpp:4:17: warning: type of ‘mult_’ does not match original declaration [-Wlto-type-mismatch] 
extern "C" void mult_(std::complex<double> *); 
       ^
mult.f90:1:1: note: ‘mult’ was previously declared here 
subroutine mult(c) 
^ 
mult.f90:1:1: note: code may be misoptimized unless -fno-strict-aliasing is used 

警告が消える: - 6(バージョンI

  • グラム++を交換してください有するG ++で)6.2.0である - 5(バージョン5.4.1)
  • コンパイル-fltoフラグ
  • 使用せず二重(代わりのstd ::の複合体)とREAL * 8(代わりの複合* 16)

私は心配すべきですか、それとも私が無視できる警告ですか?前者の場合、どのように問題を解決できますか?

+1

を心配する必要はありませんので、呼び出し規約などは、まったく同じです。次に、非標準の 'complex * 16'を' complex(c_double_complex) 'に変更し、' bind(C) 'を使うことができます。これには、C++コードでのFortranの名前のマングリングをシミュレートする必要がないという利点があります(つまり、 'mult_'ではなく' mult'を参照するだけです)。 – Yossarian

+0

それは役に立たないようですが、ISO Cバインディングが使用されているときに同じ警告が表示されます。 –

答えて

1

私は見つけることができる最も近い関連する問題は、コンパイラの警告は関係ありませんように思え https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78562#c6

です。

IはC++で次のコードをコンパイルし、FORTRANコード

extern "C" 
{ 
    void mult_(std::complex<double> *z) 
    { 
     *z = *z * *z; 
    } 
} 

で生成されたアセンブラを比較し、結果を表示する:実装がわずかに異なる(FortranがCに対し、1つでもGPレジスタを使用しないように思わ++ RBXを使用しています)がありますが、あなたはおそらくiso_c_binding` `を見てみたい++ C/Cとの相互運用性のために

rep ~ $ g++ -S -O3 -Wall test2.cpp 
rep ~ $ g++ -S -O3 mult.f90 
rep ~ $ cat mult.s 

-----------------------------Snip---------------------------- 

.LFB0: 
     .cfi_startproc 
     movsd (%rdi), %xmm0 
     movsd 8(%rdi), %xmm1 
     movapd %xmm0, %xmm2 
     movapd %xmm1, %xmm3 
     mulsd %xmm0, %xmm2 
     mulsd %xmm1, %xmm3 
     mulsd %xmm1, %xmm0 
     subsd %xmm3, %xmm2 
     addsd %xmm0, %xmm0 
     movsd %xmm2, (%rdi) 
     movsd %xmm0, 8(%rdi) 
     ret 
     .cfi_endproc 

-----------------------------Snip---------------------------- 

rep ~ $ cat test2.s 

-----------------------------Snip---------------------------- 

.LFB1991: 
     .cfi_startproc 
     movsd 8(%rdi), %xmm3 
     pushq %rbx 
     .cfi_def_cfa_offset 16 
     .cfi_offset 3, -16 
     movsd (%rdi), %xmm2 
     movq %rdi, %rbx 
     movapd %xmm3, %xmm1 
     movapd %xmm2, %xmm0 
     call __muldc3 
     movsd %xmm0, (%rbx) 
     movsd %xmm1, 8(%rbx) 
     popq %rbx 
     .cfi_def_cfa_offset 8 
     ret 
     .cfi_endproc 

-----------------------------Snip---------------------------- 
rep ~ $ 
+0

ありがとうございます。 '-flto'をリンクに使っても何も変わっていないと思いますか? –

+1

私の知る限り、生成されたコードは、規則と型を呼び出す関数が正常であることを示しています –