Gui*_*ume 2 memory-management exception clang c++11
当我尝试分配超出其限制的对象时,我无法理解clang如何抛出异常.例如,如果我编译并运行以下代码:
#include <limits>
#include <new>
#include <iostream>
int main(int argc, char** argv) {
typedef unsigned char byte;
byte*gb;
try{
gb=new byte[std::numeric_limits<std::size_t>::max()];
}
catch(const std::bad_alloc&){
std::cout<<"Normal"<<std::endl;
return 0;}
delete[]gb;
std::cout<<"Abnormal"<<std::endl;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
然后当我使用"clang ++ -O0 -std = c ++ 11 main.cpp"进行编译时,我得到的结果是"正常",但是只要我启用优化1到3,程序就会意外返回"Abnormal".
我出乎意料地说,因为根据C++ 11标准5.3.4.7:
当noptr-new-declarator中的表达式的值为零时,将调用分配函数以分配不带元素的数组.如果该表达式的值小于零或者分配的对象的大小超过实现定义的限制,或者new-initializer是一个braced-init-list,其初始化子句的数量超过了要初始化的元素数,不获取存储,并且new-expression通过抛出与std :: bad_array_new_length(18.6.2.2)类型的处理程序(15.3)匹配的类型的异常来终止.
[在linux上使用libstd ++和在Mac上使用libc ++的clang 3.3都可以观察到这种行为.删除-std = c ++ 11标志时也会观察到相同的行为.
当我使用gcc 4.8编译相同的程序时,使用完全相同的命令行选项,情节变浓.在这种情况下,程序为任何选定的优化级别返回"正常".
我在上面发布的代码中找不到任何未定义的行为,这可以解释为什么clang会在启用代码优化时不会抛出异常.就bug数据库而言,我能找到的最接近的是http://llvm.org/bugs/show_bug.cgi?id=11644,但它似乎与抛出的异常类型有关,而不是行为差异调试和发布代码之间.
所以这是Clang的一个错误?或者我错过了什么?谢谢,
看来clang在数组未使用时消除了分配:
#include <limits>
#include <new>
#include <iostream>
int main(int argc, char** argv)
{
typedef unsigned char byte;
bytes* gb;
const size_t max = std::numeric_limits<std::size_t>::max();
try
{
gb = new bytes[max];
}
catch(const std::bad_alloc&)
{
std::cout << "Normal" << std::endl;
return 0;
}
try
{
gb[0] = 1;
gb[max - 1] = 1;
std::cout << gb[0] << gb[max - 1] << "\n";
}
catch ( ... )
{
std::cout << "Exception on access\n";
}
delete [] gb;
std::cout << "Abnormal" << std::endl;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
此代码"Normal"
使用-O0和-O3 打印,请参阅此演示.这意味着在这段代码中,它实际上是尝试分配内存而确实失败了,因此我们得到了异常.请注意,如果我们不输出,clang仍然足够聪明,甚至可以忽略写入.
归档时间: |
|
查看次数: |
1224 次 |
最近记录: |