返回介绍

7.17 操作符过载

发布于 2020-09-09 22:55:47 字数 3025 浏览 1308 评论 0 收藏 0

有多种算术算法可能非常有用:饱和算法,任意尺寸的浮点数运算,进位保留算法等。使用普通的算术操作符而不是依赖于函数调用有利于代码的可读性。

overload_declaration ::=  // 引用自附录A.2.8
    bind overload_operator function data_type function_identifier (overload_proto_formals);

overload_operator ::= + | ++ | – | –– | * | ** | / | % | == | != | < | <= | > | >= | =

overload_proto_formals ::= data_type {, data_type}

语法 7-3 — 操作符重载语法(摘录自附录A)

过载声明使得算术操作符能够应用于一般情况下它们不能使用的数据类型,例如非压缩结构体。它不会改变操作符原本的含义,也就是说,当使用操作符过载的时候,原来的代码不会改变其运算行为。

过载声明将一个操作符链接到一个函数原型。在使用时,首先检查函数自变量是否匹配,然后再检查结果类型是否匹配。多个函数可以具有相同的自变量及不同的返回值。如果操作符使用在一个自决关联文中,而且不存在一个期望的返回类型,那么必须使用强制类型转换来选择正确的函数。类似地,如果由于嵌套操作符而导致可能具有多个期望的类型,并且可以与多于一个函数相匹配,那么也必须使用强制类型转换来选择正确的函数。

一个期望的结果类型存在于下列任意一个关联文中:

  • 一条赋值语句或赋值表达式的右侧
  • 一个任务或函数调用的真实输入参数
  • 一个模块、接口或程序的输入端口连接
  • 一个模块、接口、程序或类的真实参数
  • 具有明确比较的关系操作符
  • 在一个强制类型转换中

例如,假定float是一个结构体类型:

typedef struct {
    bit sign;
    bit [3:0] exponent;
    bit [10:0] mantissa;
} float;

通过调用下述过载声明中所指示的函数,+操作符能够应用于这个结构体。

bind + function float faddif(int, float);
bind + function float faddfi(float, int);
bind + function float faddrf(real, float);
bind + function float faddrf(shortreal, float);
bind + function float faddfr(float, real);
bind + function float faddfr(float, shortreal);
bind + function float faddff(float, float);
bind + function float fcopyf(float);     // 一元操作符 +
bind + function float fcopyi(int);       // 一元操作符 +
bind + function float fcopyr(real);      // 一元操作符 +
bind + function float fcopyr(shortreal); // 一元操作符 +

float A, B, C, D;
assign A = B + C;   // 等价于A = faddff(B, C);
assign D = A + 1.0; // 等价于A = faddfr(A, 1.0);

根据过载表达式中等价的自变量类型,过载声明将+操作符链接到每一个函数原型。通常,这种过载需要自变量具有精确的类型匹配。然而,一个例外是:如果真实参数具有integral类型,并且只有一个函数原型具有对应的integral类型的自变量,那么真实参数会被隐式地强制转换到原型中的类型。

注意:函数原型不需要精确地匹配于真实的函数声明。如果没有,那么在调用函数的时候应用普通的隐式强制类型转换。例如,fcopyi 函数可以被定义成具有一个int类型的自变量:

function float fcopyi (int i);
    float o;

    o.sign = i[31];
    o.exponent = 0;
    o.mantissa = 0;
    …
    return o;
endfunction

对赋值操作符的过载也会过载隐式赋值或强制类型转换。Here these are using the same functions as the unary +.

bind = function float fcopyi(int);       // 将int强制转换成float
bind = function float fcopyr(real);      // 将real强制转换成float
bind = function float fcopyr(shortreal); // 将shortreal强制转换成float

可以被过载的操作符有算术操作符、关系操作符、以及赋值操作符。注意,在这里从floatfloat的赋值操作符不能被过载,因为这种赋值本来就是合法的。类似的,在float之间的相等和不等操作符也不能被过载。

对于0或1来说,我们不能假定它的格式,所以用户不能依靠减法来得出是否相等的结论,也不能使用加法来获得递增的操作结果。类似地,对于正数或负数也不能假定它的格式,因此,比较操作必须被显式地编码。

诸如+=之类的赋值操作符从连续的+和=操作符自动构建,其中,=操作符具有标准含义。例如:

float A, B;

bind + function float faddff(float, float);

always @(posedge clock) A += B;  // 等价于A = A + B

过载声明的作用范围和可视性与数据声明遵从相同的搜索规则。在过载声明的可视范围内,过载声明必须在其使用之前声明。The function bound by the overload declaration uses the same scope search rules as a function enable from the scope where the operator is invoked.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文