这是Mac OS X 10.6 c++ std API中的一个bug吗?
Is this a bug in the Mac OS X 10.6 C++ std API?
以下代码无法在Mac OS X 10.6上编译;它在stl_algobase.h中给出一个错误,后面是"从[…"消息。
#include <vector>
int main( void )
{
std::vector<int*> *v = new std::vector<int*>( 1, NULL );
return 0;
}
为了使其编译,我必须在NULL
周围放置显式强制转换,即将其替换为(int*)(NULL)
。
不过,这看起来有点尴尬,我怀疑这真的有必要;它还使我的源代码看起来非常奇怪,结构和更长的类型名称嵌套在名称空间中,等等。
EDIT (Error message):
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h: In static member function 'static _OutputIterator std::__fill_n<true>::fill_n(_OutputIterator, _Size, const _Tp&) [with _OutputIterator = int**, _Size = int, _Tp = int]':
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h:665: instantiated from '_OutputIterator std::fill_n(_OutputIterator, _Size, const _Tp&) [with _OutputIterator = int**, _Size = int, _Tp = int]'
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_uninitialized.h:184: instantiated from 'void std::__uninitialized_fill_n_aux(_ForwardIterator, _Size, const _Tp&, std::__true_type) [with _ForwardIterator = int**, _Size = int, _Tp = int]'
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_uninitialized.h:219: instantiated from 'void std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = int**, _Size = int, _Tp = int]'
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_uninitialized.h:306: instantiated from 'void std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, std::allocator<_Tp2>) [with _ForwardIterator = int**, _Size = int, _Tp = int, _Tp2 = int*]'
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_vector.h:790: instantiated from 'void std::vector<_Tp, _Alloc>::_M_initialize_dispatch(_Integer, _Integer, std::__true_type) [with _Integer = int, _Tp = int*, _Alloc = std::allocator<int*>]'
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_vector.h:261: instantiated from 'std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = int, _Tp = int*, _Alloc = std::allocator<int*>]'
/Users/JayZ/projects/C++/test/main.cpp:6: instantiated from here
/Developer/SDKs/MacOSX10.6.sdk/usr/include/c++/4.2.1/bits/stl_algobase.h:641: error: invalid conversion from 'const int' to 'int*'
发生的事情是编译器必须选择允许多个参数的vector
构造函数重载之一:
explicit vector(size_type n, const T& value = T(),
const Allocator& = Allocator());
template <class InputIterator>
vector(InputIterator first, InputIterator last,
const Allocator& = Allocator());
第一个重载(您希望匹配的重载)要求转换实参。第二个不需要转换,因为两个参数是相同的类型。这就是编译器选择的重载。不幸的是,int
类型不具有第二个构造函数用于这些参数的所有操作。
通过将NULL
转换为int*
或将第一个参数设置为无符号(1U
)来强制参数为不同类型,如其他答案正确建议的那样,将通过强制编译器选择第一个构造函数选项来避免问题。
当我用MinGW 4.5.2编译这个时,我得到了编译错误(不同的,但原因相同,我相信)。然而,当我用MSVC(2008或2010)构建时,我没有得到任何错误。当我查看MSVC生成的代码时,它实际上匹配的是第二个重载(有两个迭代器),而不是'size和default value'重载。
"啊哈",我想,"这将在运行时某处崩溃,因为具有1
和0
值的迭代器没有任何意义"。
然而,当该构造函数的"迭代器"类型恰好是int
时,MSVC实现对vector
执行"计数/初始值"构造。
标准规定了当构造函数的InputIterator
实参满足InputIterator的要求时,构造函数必须做什么。由于int
不满足InputIterator的要求,因此该实现有一些自由来做其他事情。标准说"实现可以在类中声明额外的非虚成员函数签名"(17.4.4.4),我相信这将涵盖MSVC的行为。您看到的和我在GCC 4.5.2中看到的产生错误诊断的行为,也是标准所允许的。
我确信MSVC的行为是大多数用户想要的(直到他们将代码转移到其他编译器)。
您发布的代码为我在OS X 10.6.7上编译。我添加了一些断言,只是为了证明它正在做它看起来应该做的事情…
bash-3.2$ cat test.cpp
#include <vector>
#include <cassert>
int main()
{
std::vector<int*> *v = new std::vector<int*>( 1, NULL );
assert(v != NULL);
assert(v->size() == 1);
assert(v->at(0) == NULL);
assert(false);
return 0;
}
bash-3.2$
bash-3.2$ g++ -Wall -Wextra -Weffc++ test.cpp
bash-3.2$ ./a.out
Assertion failed: (false), function main, file test.cpp, line 10.
Abort trap
bash-3.2$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
assert(false)
是故意的:-)
感谢Mackie Messer的回答,我可以用-m32
重现你的错误。这一行修复了它(并且比强制转换更整洁):
std::vector<int*> *v = new std::vector<int*>(1U, NULL);
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 我正在用 c++ 制作一个小时钟,但遇到了"bug"或某种问题
- 这个std::vector和std::shared_ptr内存泄漏是一个bug吗
- c++ 指向另一个类 bug "no operator matches these operands."的指针
- 奇怪的bug-子例程只运行一个cout
- 我用STL写了一个bin_search,但这是一个小BUG
- 在一个简单的策略模式的bug
- for循环中的奇怪行为-一个bug
- 可变模板元编程:clang++或g++中的一个bug
- 这是GCC中的一个bug吗?
- MSVC 2013 Bug?正在从映射的容器中检索最后一个元素
- 我最近在使用abs()时遇到了一个奇怪的bug
- libc++ std::search_n中的崩溃是一个bug吗?
- 在Qt中重现一个bug:调试代码时出现分段错误
- 这是g++中的一个bug吗?
- visual studio -这(崩溃)是VS2012 c++编译器中的一个bug吗?
- 一个非常简单的加法程序(c++)上的奇怪bug
- 这是Mac OS X 10.6 c++ std API中的一个bug吗?
- 调用mysql_close获取堆栈损坏,这是MySQL中的一个bug吗?