【问题标题】:Mark as deprecated function parameters in C++14在 C++14 中标记为不推荐使用的函数参数
【发布时间】:2019-05-28 10:51:45
【问题描述】:

阅读 this blog post 及其 cmets,我注意到它作为示例提供了将特定函数参数标记为已弃用的可能性,如(示例取自帖子):

// Deprecate a function parameter
int triple([[deprecated]] int x);

现在我想知道,这样的功能有什么好的用例?在那篇文章的 cmets 中或我搜索过的任何其他地方似乎都没有任何线索。

编辑:

要查看它的实际效果,有一个可编译的示例on goldbolt

【问题讨论】:

  • 嗯。我在考虑默认参数,但 gcc 不会对void f([[deprecated]] int n = 0); void g() { f(); f(2); } 中的任何一个语句发出警告。它只在函数体内发出警告。
  • 使用gcc trunk,如你所见on goldbolt,在函数内部使用参数时发出警告,而不是在调用时发出警告,这就是为什么它是令人费解的。
  • 你为什么假设有一个用例?也许这可能只是因为没有例外禁止它。
  • @eerorika 我不是假设有一个用例。这个功能完全有可能只是碰巧在没有任何计划的情况下可用,并且保持原样无害,但我很想知道是否真的有一个用例。

标签: c++ c++14 deprecated deprecation-warning


【解决方案1】:

假设你有这样一个函数:

void* allocate(std::size_t sz, void* hint = nullptr) {
    // if you give `hint` it *might* be more efficient
}

然后你决定不再值得努力做基于hint 的东西。所以你会这样做:

void* allocate(std::size_t sz, [[deprecated]] void* hint = nullptr) {
    // `hint` is ignored. The compiler warns me if I use it in the
    // function body accidentally, and people reading the function
    // signature can see that it is probably going to be ignored.
}

这允许库保持相同的签名/ABI(因此您不需要重新编译使用它的东西,遗留代码仍然可以继续使用它而不会造成任何伤害),并且还可以防止它被意外再次使用更改功能时。

但这主要是针对函数的开发人员,而不是函数的用户,将来他们知道为什么会有一个看似“无用”的参数。

我还认为这会禁用 gcc/clang 中带有 -Werror=unused-parameter 标志的“未使用参数”警告,但事实并非如此。使用(void) deprecated_parameter 也会发出关于使用已弃用参数的警告,因此这似乎是一个错误。如果它确实禁用了未使用的参数警告,那将是[[deprecated]] 的另一个用例。

【讨论】:

  • 但是 clang++ 和 g++ 都没有真正警告对函数的任何调用,无论它们是否为 hint 提供参数。
  • @aschepler 是的,因为无论如何该参数总是被传递(即使它由于默认参数而隐式地在调用方一侧),并且它与被弃用的整个函数不同。它更像是在函数体内被弃用了,但调用者并不总是需要关心这一点。
  • 这很好。但这并不像在清理后删除参数名称那样惯用。
【解决方案2】:

规则是the attribute is valid on, amongst other things, variable declarations(广义上)。函数参数中的此类声明并未明确允许。

最初的提案N3394也没有提到这样的用例,原始功能in GCCregardless accepts the equivalent usage)或in VS(我没有检查)的文档也没有提到铿锵声)。

因此,我认为这是允许的“意外”,而不是任何人真正想到的有用的东西。

像 Artyer 所探索的那样,记录已弃用的默认参数是否有用?是的,潜在的,模糊的。但正如 Artyer 还发现的那样,主流编译器实际上并没有以有用的方式对这种用法做出反应。

因此,目前,它没有有用,并且语言功能并不是专门为在这种情况下有用而设计的。

【讨论】:

  • 虽然我可以看到这种极端情况是如何在没有计划的情况下发生的,但我认为它不太可能一直被忽视。在介绍之后的一些讨论中有没有提到它?
  • 我不认为它“没有被注意到”,我认为您只是第一个关心的人:P 毕竟,我们可以编写很多其他无用的代码,这取决于我们个人。换句话说:为什么要在语言中写一个特殊的规则来禁止它?我们将从这样的并发症中得到什么?这才是真正的症结所在。
【解决方案3】:

想象一个已实施、使用和维护多年的库。该库用于多个项目。
如果您只是删除该参数,则所有项目都必须在升级到新库版本后立即调整源代码才能再次编译。
如果将默认值添加到参数中,但不再使用该参数,则项目仍将编译而没有任何更改,但没有人会注意到某些内容已发生更改,并且可能由此参数控制的某些行为/功能确实不再工作了。

因此,通过将参数标记为已弃用,项目可以在不进行任何更改的情况下进行编译,但它们会收到警告,指出某些内容已更改并且应该更改其源代码,因为该参数迟早会消失。

【讨论】:

  • 但是 g++ 和 clang++ 都只对函数定义中的参数使用发出警告,而不是对函数的任何调用发出警告,无论它们是否为该参数提供参数。这与您所描述的相反。
猜你喜欢
  • 2019-05-13
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
相关资源
最近更新 更多