似乎 PROC FCMP 中未初始化的变量的默认长度为 33 个字节。考虑以下演示代码:
OPTIONS INSERT = (CMPLIB = WORK.FCMP);
PROC FCMP
OUTLIB = WORK.FCMP.FOO
;
FUNCTION FOO(
BAR $
);
* Assign the value of BAR to the uninitialised variable BAZ;
BAZ = BAR;
* Diagnostics;
PUT 'BAR IS ' BAR;
PUT 'BAZ IS ' BAZ;
* Return error code;
IF
LENGTH(BAZ) NE LENGTH(BAR)
THEN
RETURN(0)
; ELSE
RETURN(1)
;
ENDSUB;
RUN;
DATA _NULL_;
X = 'shortstring';
Y = 'exactly 33 characters long string';
Z = 'this string is somewhat longer than 33 characters';
ARRAY STRINGS{*} _CHARACTER_;
ARRAY RC{3} 8 _TEMPORARY_;
DO I = 1 TO DIM(STRINGS);
RC[I] = FOO(STRINGS[I]);
END;
RUN;
在我的站点安装(Base SAS 9.4 M2)中,将以下行打印到日志中:
BAR IS shortstring
BAZ IS shortstring
BAR IS exactly 33 characters long string
BAZ IS exactly 33 characters long string
BAR IS this string is somewhat longer than 33 characters
BAZ IS this string is somewhat longer th
这可能与 PROC FCMP 和 DATA 步一样,不能在运行时动态分配可变长度有关。但是,它有点令人困惑,因为它确实为参数动态分配可变长度。我假设 PROC FCMP 子例程有一个单独的“初始化”阶段,在此期间确定作为参数传递的值的长度,并将必须保存这些值的参数变量初始化为所需的长度。但是,只定义了变量的长度只有在运行时,当内存已经分配时,才能在子例程的主体中发现。因此,在运行之前(无论是在编译时还是我假设的“初始化”阶段),如果存在显式 LENGTH 语句,内存会分配给这些变量,否则会回退到默认的 33 字节。
现在真正有趣的是,PROC FCMP 在这方面非常聪明——在初始化/运行时阶段的严格分离中。如果在子例程的主体中,一个变量A
有一个明确定义的 LENGTH,然后另一个未初始化的变量B
被分配了一个函数A
,则B
设置为与 相同的长度A
。考虑对上述函数的这种修改,其中的值BAR
不是直接分配给BAZ
,而是通过第三个变量QUX
,它明确定义LENGTH
了 50 个字节:
OPTIONS INSERT = (CMPLIB = WORK.FCMP);
PROC FCMP
OUTLIB = WORK.FCMP.FOO
;
FUNCTION FOO(
BAR $
);
LENGTH QUX $ 50;
QUX = BAR;
* Assign the value of BAR to the uninitialised variable BAZ;
BAZ = QUX;
* Diagnostics;
PUT 'BAR IS ' BAR;
PUT 'BAZ IS ' BAZ;
* Return error code;
IF
LENGTH(BAZ) NE LENGTH(BAR)
THEN
RETURN(0)
; ELSE
RETURN(1)
;
ENDSUB;
RUN;
DATA _NULL_;
X = 'shortstring';
Y = 'exactly 33 characters long string';
Z = 'this string is somewhat longer than 33 characters';
ARRAY STRINGS{*} _CHARACTER_;
ARRAY RC{3} 8 _TEMPORARY_;
DO I = 1 TO DIM(STRINGS);
RC[I] = FOO(STRINGS[I]);
END;
RUN;
日志显示:
BAR IS shortstring
BAZ IS shortstring
BAR IS exactly 33 characters long string
BAZ IS exactly 33 characters long string
BAR IS this string is somewhat longer than 33 characters
BAZ IS this string is somewhat longer than 33 characters
这种“有用”的行为很可能是导致先前答案中的混淆和差异的原因。我想知道这种行为是否记录在案?
我将把它作为练习留给读者来研究智能 SAS 是如何尝试解决这个问题的。例如,如果一个未初始化的变量被分配了其他两个具有明确分配长度的变量的连接值,那么它的长度是否设置为其他两个变量的总和?