gpt4 book ai didi

loops - Gfortran -Wuninitialized 标志在 do 循环中丢失变量

转载 作者:行者123 更新时间:2023-12-04 03:19:00 24 4
gpt4 key购买 nike

考虑以下代码:

PROGRAM TEST
IMPLICIT NONE
REAL:: noninit

noninit = noninit + 1
END PROGRAM TEST

如果使用 gfortran -Wall TEST.f90 编译,则会正确生成警告,指出 ‘noninit’ 在此函数 [-Wuninitialized] 中未初始化使用。现在考虑 do 循环中的相同代码:

PROGRAM TEST

IMPLICIT NONE
REAL:: noninit
INTEGER:: ii

DO ii=1,10
noninit = noninit + 1 ! line 8
END DO

print *, "noninit = ", noninit

END PROGRAM TEST

当执行相同的命令时,不会产生未初始化变量的警告。您能否解释为什么会出现这种行为以及我可以采取什么措施来解决它?我目前的解决方案是使用 -finit-real=snan 标志来创建一个易于追踪的垃圾痕迹,如果变量未初始化。有更好的解决方案吗?

最佳答案

假定错误的特征

对于初学者来说,准确地缩小这个(假定的)错误发生的时间是有帮助的,在我看来,如果这两个条件都成立,它就会发生:

  1. 内部循环
  2. 变量出现在左右两侧(例如x=x+1)

变量是隐式声明还是显式声明,无论它们是整数还是实数,似乎都无关紧要。

因此,虽然这看起来确实是一个编译器错误,但情况非常有限,-Wuninitialized 将捕获绝大多数带有未初始化变量的错误,即使在 do 循环内部也是如此。

此外,虽然 -Wuninitialized 在上述情况下会失败,但还有一些其他 gfortran 编译器标志在这里非常有用,至少在实数方面——我不知道任何捕获整数的方法。请参阅下面的几个选项。

gfortran version = 5.5.0(linux系统测试)

捕获未声明的实数的选项 1

外壳命令:

> gfortran -finit-real=snan main.f90
> ./a.out

输出:

noninit =               NaN

注意事项:

  1. 这不会给出编译器警告,也不会导致运行时错误,但它将 NONINIT 初始化为 NaN 而不是零,这更有可能提示您解决此处的问题,但显然这取决于关于您的程序稍后使用 NONINIT 究竟做了什么。
  2. 因为此选项明确地将实数初始化为 NaN,所以它会否定您从 -Wuninitialized 获得的任何实数警告,因为现在没有实数会未初始化!但是对于大多数未初始化的整数,您仍然应该收到警告。

捕获未声明的实数的选项 2

外壳命令:

> gfortran -finit-real=snan -ffpe-trap=invalid,zero,overflow -g main.f90
> ./a.out

输出:

Program received signal SIGFPE: Floating-point exception - erroneous 
arithmetic operation.

Backtrace for this error:
#0 0x7FCE45AFC697
#1 0x7FCE45AFCCDE
#2 0x7FCE44FF73EF
#3 0x400818 in MAIN__ at main.f90:8
Floating point exception

注意事项:

  1. -ffpe-trap 的重要选项是“无效”,但我将“零”和“溢出”包括在内只是因为似乎大多数使用此标志的人似乎都使用这三个选项。
  2. 需要 -g 标志来查看导致崩溃的行号(如果没有 -g,它仍然会崩溃,但您不知道是哪一行它是)。

关于loops - Gfortran -Wuninitialized 标志在 do 循环中丢失变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39591300/

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