首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gcc 6下std::complex<double>在C++中的类型错配与复式*16的链接时间优化

gcc 6下std::complex<double>在C++中的类型错配与复式*16的链接时间优化
EN

Stack Overflow用户
提问于 2016-12-08 14:08:09
回答 1查看 604关注 0票数 1

我使用了一些科学计算代码,它调用了C++的Fortran例程,后者突然开始在gcc 6下发出警告。下面是最基本的问题:

考虑在mult中定义的Fortran子例程mult.f90

代码语言:javascript
复制
subroutine mult(c)
  complex*16 c
  c = c * c
  return
end

我从C++文件test.cpp调用它

代码语言:javascript
复制
#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编译文件时,会收到以下警告:

代码语言:javascript
复制
$ 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

如果我做了以下任何一件事情,警告就会消失:

  • 将g++-6 (我的版本为6.2.0)替换为g++-5 (版本5.4.1)
  • 没有-flto标志的编译
  • 使用double (而不是std::复杂性)和实*8(而不是复数*16)

我应该担心,还是说这是我可以忽视的警告?在前一种情况下,我如何解决这个问题?

EN

回答 1

Stack Overflow用户

发布于 2016-12-08 15:29:16

我能找到的最相关的问题是bug.cgi?id=78562#c6

编译器的警告似乎与此无关。

我用C++编译了以下代码,并将生成的汇编程序与fortran代码进行了比较

代码语言:javascript
复制
extern "C" 
{
  void mult_(std::complex<double> *z)
  {
      *z = *z * *z; 
  }
}

查看结果:实现略有不同(fortran似乎甚至不使用单个GP寄存器,而C++使用RBX),但是调用约定等都是完全相同的,所以您不必担心。

代码语言:javascript
复制
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 ~ $
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41041434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档