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
。另请注意,这仅为主代码中的例程生成绑定检查;如果在其他例程中有任何下标错误,它们将不会被捕获。当你在编译语言中遇到错误时,检测到问题的地方可能不是真正的根源,通常最好尽可能地应用调试选项。
我的代码包括主程序和我正在链接的单独文件中的许多模块。目前我有一个 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
。另请注意,这仅为主代码中的例程生成绑定检查;如果在其他例程中有任何下标错误,它们将不会被捕获。当你在编译语言中遇到错误时,检测到问题的地方可能不是真正的根源,通常最好尽可能地应用调试选项。