IDL究竟在做什么:COMPILE_OPT
17853 文章评分:
5.0
IDL究竟在做什么:COMPILE_OPT
匿名 2015年3月18日,星期三
如果你是一名现代IDL程序员,那么 compile_opt idl2 这行代码应该出现在你编写的每个函数/过程/方法/$MAIN程序的顶部。如果没有,我将在此说服你为什么应该加上它。
首先,compile_opt 到底是什么?compile_opt 是一个语句,由IDL编译器处理,用于改变编译器的行为。它会按照语句的顺序进行处理(这意味着如果你把 compile_opt 放在代码中间,它的效果只会应用于 compile_opt 之后的代码)。
compile_opt idl2 有什么作用?idl2标志为IDL编译器设置了两个标志:DEFINT32和STRICTARR。DEFINT32将IDL整数的默认大小设置为32位而非16位。这很有用,因为它使IDL的默认行为与C语言长整型的标准大小保持一致,因此你可以依赖长整型更宽泛的-2147483648和2147483647下溢/上溢值。STRICTARR 则阻止IDL使用圆括号进行数组索引。
为什么这很重要?考虑以下代码:
offset = input(**0**)
data = input[**100**] \* offset
input是什么?非类型化语言的一个难点在于难以从小的上下文判断代码的意图。在这种情况下,input可能是一个函数和一个数组,或者是一个以两种不同方式访问的数组(在没有 compile_opt idl2 的情况下,这是有效的语法)。通过在每一个函数的开头始终加上 compile_opt idl2,这种歧义就被消除了。
你可能会想:“但是我喜欢用圆括号索引数组,我只需要在我写的新代码里加上 compile_opt idl2 就行了”。借用一位曾经伟大的机器人的话:“危险!危险,威尔·罗宾逊!”考虑以下情况:
test22.pro
PRO test22
resolve_routine, 'a', /either,/compile_full_file
print, 'Answer = ', b('stuff')
END
----
a.pro
FUNCTION b, istuff COMPILE_OPT idl2, hidden
RETURN, 'b'
END
FUNCTION a, istuff COMPILE_OPT idl2
RETURN, 'a'
END
如果你尝试运行 test22,函数 b 将不会被解析。这是因为test22.pro的符号是在 resolve_routine 之前生成的,并且由于没有对 b 的引用,它将被视为一个变量。在 resolve_routine 之后,编译器不会将变量 b 的类型覆盖为函数。如果你在代码中间使用 compile_opt idl2,也会出现同样的问题。当IDL感到困惑时,你就输了。
以下是一些简单的技巧,可以帮助你避免这些陷阱:
- 始终将 compile_opt idl2 放在你的函数/过程的顶部。
- 如果你的函数没有 compile_opt idl2,请加上它!最坏的情况是,你需要将数组的圆括号索引重构为方括号。但这个简单的重构将让你的代码更具可读性和可扩展性,从而减少未来的麻烦。
- 如果你正在处理遗留代码(并且坚持保持其遗留代码状态),请注意外部代码是否使用了 compile_opt idl2。如果是,请仔细检查你的函数/过程/变量名称,以防止IDL产生混淆。