考虑以下使用的简单代码new(我知道没有delete[],但它与此问题无关):
int main()
{
int* mem = new int[100];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是否允许编译器优化new呼叫?
在我的研究中,g ++(5.2.0)和Visual Studio 2015不会优化new呼叫,而clang(3.0+)则可以.所有测试都是在启用完全优化的情况下进行的(-O3用于g ++和clang,用于Visual Studio的发布模式).
是不是new在引擎盖下进行系统调用,使编译器无法(并且非法)优化它?
编辑:我现在已经从程序中排除了未定义的行为:
#include <new>
int main()
{
int* mem = new (std::nothrow) int[100];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑2:
#include <new>
int main()
{
int* mem = new (std::nothrow) int[1000];
if (mem != 0)
return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
鉴于此应用程序:
#include <iostream>
struct X {
X(int _x) { x = _x + 1; }
X(const X& that) { x = that.x + 10; }
X& operator=(const X& that) { x = that.x + 100; return *this; }
X(X&& that) { x = that.x + 1000; }
X& operator=(X&& that) { x = that.x + 10000; return *this; }
int x;
};
int main() {
X a(1);
std::cout << "a.x=" << a.x << std::endl;
X b = 2;
std::cout << …Run Code Online (Sandbox Code Playgroud) 我想创建一个const std::vector<T>可以存储用户代码可以访问但不能(轻松)修改的可更新值的值。这样做有几个优点。矢量对象(但不能更改其内容)无法更改。因此,如果有人稍后决定添加新元素或其他可能导致悬空引用的操作,则可以建立对向量中条目的引用,而不会产生悬空引用。而且,由于它是一个完整的 const 对象,因此即使placement-new没有 UB 和/或编译器投诉,也无法对其进行修改。
这似乎是可能的,因为虽然向量对象是 const,但Ts 不是且必须存储为非常量。尝试将它们存储为 const 会产生以下错误:
C++ 标准禁止 const 元素的容器,因为
allocator<const T>其格式不正确。
看到这个
因此,由于T不是 const,而是仅在访问时才显示为 const,因此似乎可以通过使用 aconst_cast来删除 const 来访问和更新它们。
我还没有遇到过这种可修改 const 向量的使用,但它似乎是相当合法的。我错过了什么吗?
constexpr以下是包含额外 UB 测试的代码:
#include <vector>
#include <iostream>
constexpr int foo()
{
const std::vector<int> v{ 1,2,3 };
const int& rci = v[0]; // A const ref to v[0] is ok
int& ri = const_cast<int&>(v[0]); // A ref to v[0] as a …Run Code Online (Sandbox Code Playgroud)