gpt4 book ai didi

fortran - 什么是 undefined reference /未解析的外部符号错误以及如何在 Fortran 中修复它?

转载 作者:行者123 更新时间:2023-12-04 14:39:24 25 4
gpt4 key购买 nike

我正在尝试构建 Fortran 程序,但我收到有关 undefined reference 或未解析外部符号的错误。我见过another question关于这些错误,但那里的答案大多特定于 C++。
用 Fortran 编写时这些错误的常见原因是什么,我该如何修复/防止它们?

最佳答案

像这些消息这样的链接时错误的原因可能与链接器的更一般用途相同,而不仅仅是编译了 Fortran 程序。其中一些包含在 linked question 中。关于 C++ 链接和在 another answer此处:未能指定库,或以错误的顺序提供它们。
但是,在编写 Fortran 程序时有一些常见的错误会导致链接错误。
不支持的内在函数
如果子例程引用旨在引用内部子例程,那么如果编译器不提供该子例程内部函数,则这可能导致链接时错误:它被视为外部子例程。

  implicit none
call unsupported_intrinsic
end
unsupported_intrinsic编译器未提供,我们可能会看到链接错误消息,例如
undefined reference to `unsupported_intrinsic_'
如果我们使用的是非标准的,或者没有普遍实现的内在函数,我们可以通过以下几种方式帮助我们的编译器报告:
  implicit none
intrinsic :: my_intrinsic
call my_intrinsic
end program
my_intrinsic不是受支持的内在函数,那么编译器会提示一条有用的消息:
Error: ‘my_intrinsic’ declared INTRINSIC at (1) does not exist
我们使用内在函数没有这个问题,因为我们使用的是 implicit none :
  implicit none
print *, my_intrinsic()
end
Error: Function ‘my_intrinsic’ at (1) has no IMPLICIT type
对于某些编译器,我们可以使用 Fortran 2018 implicit对子程序执行相同操作的语句
  implicit none (external)
call my_intrinsic
end
Error: Procedure ‘my_intrinsic’ called at (1) is not explicitly declared
外部过程代替模块过程
正如我们可以尝试在程序中使用模块过程,但忘记将定义它的对象提供给链接器,我们可能会不小心告诉编译器使用外部过程(具有不同的链接符号名称)而不是模块过程:
module mod
implicit none
contains
integer function sub()
sub = 1
end function
end module

use mod, only :
implicit none

integer :: sub

print *, sub()

end
或者我们可能完全忘记使用该模块。同样,我们经常在错误地引用外部过程而不是 sibling module procedures 时看到这一点。 .
使用 implicit none (external)当我们忘记使用模块时可以帮助我们,但这不会捕获我们显式声明函数为外部函数的情况。我们必须小心,但如果我们看到像这样的链接错误
undefined reference to `sub_'
那么我们应该认为我们已经引用了一个外部过程 sub而不是模块过程:“模块 namespace ”没有任何名称修改。这是我们应该寻找的强烈提示。
错误指定的绑定(bind)标签
如果我们与 C 进行互操作,那么我们很容易错误地指定符号的链接名称。不使用标准互操作性工具时很容易,我不会费心指出这一点。如果您看到与 C 函数应该是什么相关的链接错误,请仔细检查。
如果使用标准设施,仍有绊倒的方法。区分大小写是一种方式:链接符号名称区分大小写,但如果不是全部较低,则必须告知 Fortran 编译器大小写:
   interface
function F() bind(c)
use, intrinsic :: iso_c_binding, only : c_int
integer(c_int) :: f
end function f
end interface

print *, F()
end
告诉 Fortran 编译器向链接器询问符号 f ,即使我们称它为 F这里。如果符号真的被称为 F ,我们需要明确地说:
   interface
function F() bind(c, name='F')
use, intrinsic :: iso_c_binding, only : c_int
integer(c_int) :: f
end function f
end interface

print *, F()
end
如果您看到因大小写而异的链接错误,请检查您的绑定(bind)标签。
这同样适用于具有绑定(bind)标签的数据对象,并确保任何具有链接关联的数据对象在任何 C 定义和链接对象中都有匹配的名称。
不提供主程序
除非另有说明,编译器通常会假设它正在编译主程序以生成(使用链接器)可执行文件。如果我们不编译一个不是我们想要的主程序。也就是说,如果我们正在编译一个模块或外部子程序,供以后使用:
module mod
implicit none
contains
integer function f()
f = 1
end function f
end module

subroutine s()
end subroutine s
我们可能会收到类似的消息
undefined reference to `main'
这意味着我们需要告诉编译器我们没有提供 Fortran 主程序。这通常与 -c 一起使用标志,但如果尝试构建库对象会有不同的选择。在这种情况下,编译器文档将提供适当的选项。

关于fortran - 什么是 undefined reference /未解析的外部符号错误以及如何在 Fortran 中修复它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66855252/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com