这个C++静态分析规则按原样有意义吗
Does this C++ static analysis rule make sense as is?
我正在实现一些C++静态分析规则,其中一个规则禁止函数返回指向该函数引用参数的引用或指针,即以下都是不兼容的:
int *f(int& x) { return &x; } // #1
const int *g(const int& x) { return &x; } // #2
int& h(int& x) { return x; } // #3
const int& m(const int& x) { return x; } // #4
对此给出的理由是,"无论参考参数是临时对象还是对参数的引用,这都是实现定义的行为。"
然而,我对此感到困惑,因为C++中的流运算符是这样写的,例如
std::ostream& operator<<(std::ostream& os, const X& x) {
//...
return os;
}
我相信C++中的流运算符通常不会表现出实现定义的行为,那么这是怎么回事呢?
根据我目前的理解,我希望#1和#3是定义明确的,因为临时变量不能绑定到非常量引用,所以int& x
指的是一个生存期超出函数范围的真实对象,因此返回指向该对象的指针或引用是可以的。我认为#2是不可靠的,因为临时地址可能绑定到const int& x
,在这种情况下,试图获取其地址似乎是一个糟糕的计划。我不确定4号——我的直觉是,这也可能是不可靠的,但我不确定。特别是,我不清楚在以下情况下会发生什么:
const int& m(const int& x) { return x; }
//...
const int& r = m(23);
正如您所说,#1和#3很好(尽管#1可以说是糟糕的风格)。
#4是不可靠的,原因与#2相同;它允许将const引用传播到已过其生存期的临时对象。
让我们检查一下:
#include <iostream>
struct C {
C() { std::cout << "C()n"; }
~C() { std::cout << "~C()n"; }
C(const C &) { std::cout << "C(const C &)n"; }
};
const C &foo(const C &c) { return c; }
int main() {
const C &c = foo(C());
std::cout << "c in scopen";
}
该输出:
C()
~C()
c in scope
在C++11中,如果还存在右值引用重载,则#2和#4可以是安全的。因此:
const int *get( const int &x ) { return &x; }
const int *get( const int &&x ) { return nullptr; }
void test() {
const int x = 0;
const int *p1 = get( x ); // OK; p1 is &x.
const int *p2 = get( x+42 ); // OK; p2 is nullptr.
}
因此,尽管它们是不可靠的,但如果程序员知道它们在做什么,它们确实有安全的用途。禁止这种行为将是严厉的。
(如果常量值引用重载是私有的、未定义的,或者以其他方式导致编译时或链接时错误,也许会更安全。对于#4的情况尤其如此,在这种情况下,我们返回引用,但没有什么好的东西可以返回引用,而且语言不允许引用为null。)
相关文章:
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 从头开始为应用程序创建 docker 映像是否有意义?
- 按原样保存用户输入 - Ruby on Rails
- 在c++中,如果首先禁止默认构造,那么禁止复制构造有意义吗
- 如何检查输入是否为字符并显示它是"invalid input",否则它将按原样运行
- sizeof(函数)有意义吗?
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- 在 C++17 中使用 const std::string& 参数有意义吗?
- 基础类模板参数的有意义名称
- 内联这个函数,确实有意义
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 左移负整数为零是否有意义?
- 是否有一个上下文表达式`a.b :: c`有意义
- 是否有一些有意义的统计数据来证明保持有符号整数算术溢出未定义是合理的
- 将可选与reference_wrapper相结合是否有意义?
- 函数返回rvalue参考是否有意义
- 将 [[noreturn]] 添加到主函数是否有意义
- 这个C++静态分析规则按原样有意义吗