对函数调用(堆栈帧)中的类型强制转换感到困惑



考虑以下示例:

create or replace function f(n integer) return integer as
begin
return n;
end;
/
begin
dbms_output.put_line(f(3.8));
end;
/
3.8

PL/SQL procedure successfully completed.

这对我来说没有意义。显然,PL/SQL在进入和退出函数时都忽略了integer规范。这仅仅是一个bug吗?这是语言开发者故意做出的设计选择吗?

这就是为什么我觉得这很困惑。对比下面的例子:

declare
x integer;
begin
x := 3.8;
dbms_output.put_line(x);
end;
/
4

PL/SQL procedure successfully completed.

在本例中,遵循数据类型规范。PL/SQL不会抛出错误,但至少它执行了隐式强制转换,并且不会违反为x声明的数据类型-变量存储值4,一个整数,而不是3.8。

那么,PL/SQL在第一个例子中是如何做函数调用的呢?据我所知(从未接受过正式的计算训练),每当编译器或解释器发现函数调用时,它都会创建一个堆栈框架,其中包含传递给函数的参数和从函数返回的返回值的变量。当堆栈帧被创建时,这些变量不应该是相同的数据类型吗?在函数声明中指定?如果堆栈帧有一个字段的integer数据类型的参数3.8,为什么不强制4之前,它甚至被存储在相应的变量?对于返回值也是同样的事情:如果函数返回3.8,但调用者期望一个整数(因此堆栈帧中相应的变量应该是integer

),它如何能够接受返回值3.8?而且,最令人不安的是-为什么这种行为与显式声明的变量所涉及的行为不同(如我的第二个例子)?

感谢分享你的想法!

答案在Oracle数据库的文档中找到(你的问题绝对没有任何关系)。

首先,上述数据库中的INTEGERNUMBER(38)的同义词。在给NUMBER(38)变量x赋值时,如在第二个示例中,根据赋值规则,NUMBER(具有任意精度)字面值3.8被舍入。

在你的第一个例子中,没有赋值发生,因为IN参数到PL/SQL子程序是通过引用传递的,并且返回了相同的引用(对NUMBER值3.8)。

最新更新