Fortran语言的Pb<-&燃气轮机;C++;如果我使用-finit local zero选项编译fortran,则具有互操作性 我在用C++和FORTRAN连接程序时发现了一个奇怪的结果。 测试(见后)非常简单:在FORTRAN模块中定义变量并在C++程序中访问它。 如果我使用“-finit local zero”选项编译fortran(GCC 7.4.0中的gfortran),则链接会失败,并抱怨变量的多重定义。当然,如果我抑制这个选项,它工作得很好,但它对我来说是一个pb,因为我需要将我的未初始化数据设置为“0” 我在FORTRAN代码之后,C++代码和EXE.
Fortran语言的Pb<-&燃气轮机;C++;如果我使用-finit local zero选项编译fortran,则具有互操作性 我在用C++和FORTRAN连接程序时发现了一个奇怪的结果。 测试(见后)非常简单:在FORTRAN模块中定义变量并在C++程序中访问它。 如果我使用“-finit local zero”选项编译fortran(GCC 7.4.0中的gfortran),则链接会失败,并抱怨变量的多重定义。当然,如果我抑制这个选项,它工作得很好,但它对我来说是一个pb,因为我需要将我的未初始化数据设置为“0” 我在FORTRAN代码之后,C++代码和EXE.,c++,c++11,gcc,linker,fortran,C++,C++11,Gcc,Linker,Fortran,module A_module USE ISO_C_BINDING implicit none real(C_FLOAT) , bind(C) :: isareal integer(C_INT), bind(C, NAME="MMS") :: MMS CONTAINS subroutine CHANGE() bind(c) use iso_c_binding i
module A_module
USE ISO_C_BINDING
implicit none
real(C_FLOAT) , bind(C) :: isareal
integer(C_INT), bind(C, NAME="MMS") :: MMS
CONTAINS
subroutine CHANGE() bind(c)
use iso_c_binding
implicit none
isareal = 5.0
MMS=40
write(*,*) 'fortran changes isareal =>',isareal
write(*,*) 'fortran changes MMS =>',MMS
end subroutine CHANGE
end module
以下是错误(使用-finit local zero时)
谢谢你的帮助……/P> < P>这个问题实际上是(至少部分地)在C++代码中。您没有告诉我,
isaral
和MMS
是外部的,因此编译器将为它们生成一个“实例化”符号(引号,因为我不记得正确的术语)。您可以通过例如“readelf-s main.o”看到这一点
这里需要注意的关键点是,Ndx
列(最后一列的下一列,符号名称旁边)表示MMS
在第4节中
如果将C++代码添加到<代码> iSARALL 和-finit local zero
编译Fortran代码,Fortran编译器还将生成“实例化”符号。然后,当你试图将它们链接在一起时,你会得到“多重定义”错误。现在,如果省略-finit local zero
选项,GFortran将把这两个符号放在COM
部分(缩写为COMDAT
),这是一种特殊的部分,允许多个定义。我不知道为什么会这样做,尽管我猜COMDAT
不允许将符号初始化为某个值
如果你搜索GCC bugzilla,你会发现一堆与多定义问题相关的Fortran问题,所有这些问题在错综复杂的小段落中相互关联。问题在于
extern "C" {
void change();
float isareal;
int MMS; //
}
定义这些变量的存储。它不仅仅是宣布它们。
下面是一个简单的例子:
$ cat x.cpp
extern "C" { int foo; }
$ make x.o
g++ -c -o x.o x.cpp
$ nm x.o
0000000000000000 B foo
extern“C”不使变量为extern;它定义了C约定的链接,即未混合的函数名。由于文件作用域变量名没有损坏(不能重载),因此无需将它们保留在那里:
extern "C" {
void change();
}
extern float isareal;
extern int MMS;
我们应该做到这一点
可能是通过使用-finit local zero,您阻止了链接器合并两个完全相同的全局定义 我以为
Pb
是lead
的化学名称,但你不是这个意思吧。你所说的Pb
是什么意思?你的评论说写“彩信”而不是“彩信”很重要。您已经编写了MMS。感谢您的评论:评论“MMS”或“MMS”:它与pb没有直接关系(问题),只是要注意,如果我们没有在fortran中明确地命名绑定(C),name=“MMS”,那么这个变量将变为“MMS”(只是为了不忘记这一点)。“真正的”问题是,我无法使用我在帖子中提到的标志编译fortran代码。在fortran代码中,ATALY写入MMS=0
是否存在问题(pb)?非常感谢,James,解释很清楚,修改也很好。
0000000000000000 4 OBJECT GLOBAL DEFAULT 4 MMS
extern "C" {
void change();
float isareal;
int MMS; //
}
$ cat x.cpp
extern "C" { int foo; }
$ make x.o
g++ -c -o x.o x.cpp
$ nm x.o
0000000000000000 B foo
extern "C" {
void change();
}
extern float isareal;
extern int MMS;