有“函数属性正确性”这样的东西吗?

问题描述 投票:0回答:1

好吧,C23 为语言添加了函数属性,但我不确定是否有人真正考虑过它们应该如何使用。考虑这个例子:

[[deprecated]] int foo () { return 0; }
[[nodiscard]]  int bar () { return 0; }

int main()
{
  typedef int foo_t ();
  foo_t* fp1;
  foo_t* fp2;
  foo_t* fp3;

  fp1 = foo;
  fp2 = fp1;
  fp3 = bar;
  fp1();
  fp2();
  fp3();
}

这里需要注意的一些事项:

  • 我不可能在
    typedef
    中指定属性,因为显然属性没有附加到类型。
  • 整个程序中我在 gcc 或 clang 中收到的唯一警告是在
    fp1 = foo;
    分配期间。
    foo
    已弃用。
  • 将 fp1 分配给 fp2 时,我没有收到警告。
  • 通过
    fp1
    fp2
    调用已弃用的函数时,我没有收到警告。
  • 我在调用
    fp3
    时没有收到警告,但忽略/丢弃结果。

此外,函数声明和定义之间似乎没有检查。这可以干净地编译:

[[unsequenced]] int foo ();
[[nodiscard]]   int foo ();
[[deprecated]]  int foo () { return 0; }

为什么我希望编译器允许这样的废话?

函数属性不附加到类型上,那么我们如何才能获得“函数属性正确性”并使其按预期工作呢?或者它们只是简单地未指定/损坏,随心所欲地添加到语言中,以便稍后当有人愿意真正检查它们的后果时修复?

我在这里遗漏了什么吗?

c c23 function-attributes
1个回答
0
投票

deprecated
的正常用途是某些软件(例如图书馆)的发行商通知客户某些项目已被弃用。为此,他们会在发布的标头中标记函数的声明,而不是函数的定义。当客户端翻译单元使用标记为
deprecated
的项目时,编译器将生成诊断信息。

这足以向客户告知问题。当从该项目复制该项目的值(或有效值,当功能指示符自动转换为地址时)以后进一步使用时,不会产生进一步的诊断,这一事实不会否定初始诊断。此属性无意修改类型和更改有关类型及其在赋值等中的角色的语义。其目的是在客户端使用已弃用的项目时提供诊断,并且它实现了这一点。

使用

nodiscard
,不幸的是属性不能传播到值的副本,但缺点是情况和/或C历史所迫;这不是由于属性设计错误造成的。一些程序将函数地址存储在公共数组中,或者动态地将动态选择的函数地址分配给公共指针。数组元素或公共指针具有单一类型,因此我们不能指定
nodiscard
函数与非
nodiscard
函数是不同的类型。在某些代码结构中,编译器分析可能能够跟踪分配给指针的值,并能够在已知
p();
保存
p
函数的地址时警告
nodiscard
丢弃返回值,但这一般情况下当然不可能。完全跟踪
nodiscard
需要执行时支持。

© www.soinside.com 2019 - 2024. All rights reserved.