gfortran:...的多个定义首先在这里定义

gfortran: multiple definitions of... first defined here

我的代码包括主程序和我正在链接的单独文件中的许多模块。目前我有一个 makefile 为每个模块创建 .o 文件(一个在单独的行上)然后我把它们放在一起,比如这里:

mpif90 - modutils
mpif90 -c modvarsym
mpif90 -c s1_Phi.f90
mpif90 -c s2_Lambda.f90

mpif90 maincode.f90 modutils.o modvarsym.o  s1_Phi.o s2_Lambda.o -o maincode 

以上编译正常并且运行正常 - 除了 tat 我怀疑我怀疑我的变量中存在数组绑定问题。所以我包括 -fbounds-check maincode 语句,如下所示:

mpif90 maincode.f90 modutils.o modvarsym.o  s1_Phi.o s2_Lambda.o -o -fbounds-check maincode 

那时会出现大量 "multiple definition" 错误,代码将不再编译。我想这是因为 -fbounds-check: 而不是仅仅启用检查数组边界,它可能会做一些额外的检查。我还怀疑错误出在我在 make 文件中输入文件的方式上。但是我找不到可行的方法。在这些文件中,modvarsym 和 modutils 都被主代码和其他两个模块使用。主要代码使用所有四个模块。 这些文件中没有 include 语句。 Maincode是唯一带有程序语句的文件,变量在modvarsym中只声明一次。总的来说,代码在没有 -fbounds-check 的情况下编译和运行。但是我真的想使用 -fbounds-check 来确保数组不会溢出。有人能让我走上正轨吗?谢谢。

这是@dave_thompson_085评论里给出的答案,好像解决了问题。

首先,我假设您的第一个命令应该有 -c,而您的前两个命令应该有 .f90(或 .f95 或类似的)后缀,否则编译器不应该为他们做任何事。其次,-o -fbounds-check maincode(在没有 -c 的情况下)意味着将链接的输出放在文件 -fbounds-check 中,并在链接的文件中包含 maincode(如果存在)。由于您已经将所有例程链接到 maincode,因此再次链接这些相同的例程加上 maincode 会产生重复项。

至少在-o之前移动-fbounds-check;更好的是,将影响解析和代码生成的选项也放在源文件之前是通常的风格(尽管不是必需的),在您的示例中是 maincode.f90。另请注意,这仅为主代码中的例程生成绑定检查;如果在其他例程中有任何下标错误,它们将不会被捕获。当你在编译语言中遇到错误时,检测到问题的地方可能不是真正的根源,通常最好尽可能地应用调试选项。