我使用了一些科学计算代码,它调用了C++的Fortran例程,后者突然开始在gcc 6下发出警告。下面是最基本的问题:
考虑在mult中定义的Fortran子例程mult.f90
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如果我做了以下任何一件事情,警告就会消失:
-flto标志的编译我应该担心,还是说这是我可以忽视的警告?在前一种情况下,我如何解决这个问题?
发布于 2016-12-08 15:29:16
我能找到的最相关的问题是bug.cgi?id=78562#c6
编译器的警告似乎与此无关。
我用C++编译了以下代码,并将生成的汇编程序与fortran代码进行了比较
extern "C"
{
void mult_(std::complex<double> *z)
{
*z = *z * *z;
}
}查看结果:实现略有不同(fortran似乎甚至不使用单个GP寄存器,而C++使用RBX),但是调用约定等都是完全相同的,所以您不必担心。
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 ~ $https://stackoverflow.com/questions/41041434
复制相似问题