考虑这个例子:
#include <iostream>
std::string& fn(std::string& str) {
str = "oh no!";
return str;
}
int main() {
std::string str = fn(str);
std::cout << str << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我有两个问题
为什么这个编译/为什么编译器不警告它?显然,在初始化之前str不应(在函数调用中)引用它。fnC++ 标准不阻止这种情况吗?如果是这样,在初始化变量之前引用变量的目的是什么?
这段代码在我尝试过的所有编译器(GCC、Clang 和 MSVC,如https://godbolt.org/z/jExWYW6b9所示)上编译良好,并且在 Godbolt 上的所有编译器上都存在段错误。但是,我可以编译此代码并在 M1 mac 上执行,而不会出现段错误Apple clang version 13.1.6 (clang-1316.0.21.2.5)(使用 Rosetta 2 在 arm64 和 x86_64 下进行测试,并打印oh no!到标准输出)。为什么这可以与 Apple Clang 一起使用并且不会出现段错误?我似乎无法在 Godbolt 上重现这一点。
此代码在运行时在复制构造函数中失败.
但是编译器(MSVS2008)没有发出警告.
你能解释(最好引用标准)这段代码是非法的还是什么?
我明白A a = a; 永远不应该写在第一位,但我正在寻找理论背景.
class A
{
public:
A()
:p(new int)
{
}
A(const A& rv)
{
p = new int(*rv.p);
}
~A()
{
delete p;
}
private:
int *p;
};
int main()
{
A a = a;
}
Run Code Online (Sandbox Code Playgroud) 来自 cppreference:
在前一个和下一个序列点之间,标量对象必须通过表达式的计算最多修改一次其存储的值,否则行为是未定义的。
代码示例:
int a = store_and_return_value(&a);
Run Code Online (Sandbox Code Playgroud)
对于 C 和 C++。