好的,在我开始之前:我知道这真的很糟糕。如果有一个每个人都遵循的设计协议,那我就要求对一个不会发生的情况进行破解。但这是我的问题。
我有一个庞大的Fortran代码库,带有错误报告例程。只有在发生奇怪的事情时才会调用错误报告例程,并且它具有整数输入:ErrorCode
。正值表示错误和中止,负值表示警告并继续。
这是我的问题:
有些人已经开始调用错误报告功能:
ErrorCode = -5
call error_report(ErrorCode)
if (ErrorCode /= 0) stop "Hey, you were supposed to reset ErrorCode"
我不知道是否有任何对error_report
实际上希望将ErrorCode
为error_report
重置为0的调用。我所知道的是call error_report(-5)
的当前实现这样做,我不想改变任何功能。
其他人让自己更轻松:
ErrorCode
目前,在例程中,INTENT
未声明任何INTENT(INOUT)
,只是为了编译代码。但当然这只意味着无论何时以第二种方式调用警告,而不是显示警告并继续工作,程序会出现段错误。
我现在没有时间和权限来正确清理代码(通常我只是将其设置为error_report
然后让编译器告诉我需要进行更改的地方。但是这个由于各种原因,目前不是一种选择。)
有没有什么方法可以编写一个满足两个版本的例程print((stats!["reward_listing"]! as? NSDictionary)!)
?程序重载?区分变量和常量的一些方法?什么?
答案 0 :(得分:3)
这个想法应该适用于任何* nix系统......主要思想是将常量文字作为符号编译到二进制文件中,而变量则不是。
因此,如果您使用ld
进行链接,则会在最终位置插入符号_end
(对于静态和动态链接)。
这可以(ab)用来检查给定的伪参数在_end
之前或之后是否具有地址。如果地址较低,则实际参数为常量,否则为(临时)变量。
然而,这需要一些C代码:
<强> addr.c 强>
int isConstant(int *x){
extern void *_end;
if ( (void *)x > (void *)&_end ) {
return 1; // Variable
} else {
return 0; // Constant
}
}
<强> test.F90 强>
program test
use,intrinsic :: ISO_C_Binding
interface
integer(C_INT) function isConstant(a) bind(C, name="isConstant")
use,intrinsic :: ISO_C_Binding
integer(C_INT), intent(in) :: a
end function
end interface
integer :: i
integer,parameter :: ii=2
i = 1
print *,isConstant(i)
print *,isConstant(1)
print *,isConstant((i))
print *,isConstant(ii)
end program
将其编译为
gfortran -Wall -Wextra test.F90 addr.c
它会给你:
./a.out
1
0
1
0
请注意,我没有使用mingw在Windows上测试Windows 。使用风险由您自己承担。
请注意,常量表达式(i)
不能按标准定义。但是,它是在运行时创建的,因此不是符号。这在输出中很明显。
但是,在OP的上下文中,我在尝试为其赋值时没有遇到段错误。