为何C++的[[nodiscard]]属性不具备传递性?
关于[[nodiscard]]的生效逻辑及意义
先看你的代码示例:
[[nodiscard]] float val() { return 3.; } float junk() { return val(); } int main() { junk(); }
为什么编译时没有警告?
[[nodiscard]]的约束只作用于直接丢弃被标记函数返回值的场景:
- 要是你直接写
val();,编译器会立刻警告,因为你丢弃了被标记为不可随意丢弃的返回值; - 但在
junk()里,val()的返回值并没有被丢弃——它被用作junk()的返回值,属于“被使用”的范畴,完全符合[[nodiscard]]的设计要求,所以不会触发警告。
C++标准并没有规定“传递nodiscard返回值的函数必须也标记[[nodiscard]]”,这是刻意的设计:中间函数是否需要加标记,取决于它自身的返回值是否需要被调用者重视,而不是被上游函数的属性强制绑定。
[[nodiscard]]标记val的意义在哪?
它的核心作用是阻止直接调用val的代码随意丢弃返回值。比如如果有开发者在某处直接调用val();却不处理返回值,编译器会马上抛出警告,提醒这个返回值可能承载着重要信息(比如错误状态、资源句柄、关键计算结果等)。
至于junk()是否需要加[[nodiscard]],完全由junk()的功能定位决定:如果junk()的返回值同样需要被调用者留意,那开发者应该主动给junk()也加上标记;如果junk()的返回值是可以安全丢弃的,那不加也完全合理。
内容的提问来源于stack exchange,提问作者Lorah Attkins
相关产品推荐
相关产品推荐

