我正在使用lldb在Xcode5中调试一个C++程序,我想在调试器中计算任意表达式,特别是那些使用重载操作符的表达式。
例如,我创建了一个非常简单的Xcode5 C++项目,并将以下main.cpp和所有编译器/链接器/etc选项设置为默认值:
#include <iostream>
#include <vector>
int main(int argc, const char * argv[])
{
std::vector<int> vec;
vec.push_back(42);
std::cout << "vec[0] = " << vec[0] << std::endl;
return 0;
}
我在return 0;
行上设置了一个断点并运行了程序。
然后,在lldb提示符下,将向量打印为一个整体:
(lldb) expr vec
(std::__1::vector<int, std::__1::allocator<int> >) $0 = size=1 {
[0] = 42
}
但是,我不能使用重载的operator[]
访问它的成员
(lldb) expr vec[0]
error: call to a function 'std::__1::vector<int, std::__1::allocator<int> >::operator[](unsigned long)' ('_ZNSt3__16vectorIiNS_9allocatorIiEEEixEm') that is not present in the target
error: The expression could not be prepared to run in the target
类似地,我无法获得迭代器(尽管我在这方面的经验较少,因此我的语法可能是错误的):
(lldb) expr vector<int>::iterator it = vec.begin()
error: use of undeclared identifier 'vector'
error: expected '(' for function-style cast or type construction
error: expected '(' for function-style cast or type construction
error: 3 errors parsing expression
和
(lldb) expr (vector<int>::iterator) vec.begin()
error: use of undeclared identifier 'vector'
error: expected '(' for function-style cast or type construction
error: expected '(' for function-style cast or type construction
error: 3 errors parsing expression
类似地,打印一个简单的字符串也很好:
(lldb) expr string("a")
(std::__1::string) $0 = "a"
但是,简单的字符串连接会失败:
(lldb) expr string("a") + string("b")
error: invalid operands to binary expression ('string' (aka 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >') and 'string')
error: 1 errors parsing expression
我做错了什么?lldb是否支持使用重载运算符进行求值?
提前谢谢你!
发布于 2013-12-11 01:36:01
注意,C++标准库是这样设置的:它们内联它们可以合理地内联的所有模板化函数,并且不存在真正的函数副本。因此,例如,当您调用std::vector<int>::begin()
时,没有这样的函数。它的所有用法都被内联了。
这就是为什么你会收到关于“调用函数...不存在于目标中”的错误。可能有函数的内联副本,但没有我们可以实际调用的副本。举个例子,如果我构建了一个生成std::vector的小C++程序,并将一些元素推入其中,然后迭代它们,然后执行以下操作:
(lldb) image lookup -r -n begin
2 matches found in /private/tmp/vector:
Address: vector[0x0000000100000eaf] (vector.__TEXT.__text + 1071)
Summary: vector`main + 1071 [inlined] std::__1::vector<int, std::__1::allocator<int> >::begin() at vector.cpp:12
vector`main + 1071 at vector.cpp:12 Address: vector[0x0000000100000eaf] (vector.__TEXT.__text + 1071)
Summary: vector`main + 1071 [inlined] std::__1::vector<int, std::__1::allocator<int> >::begin() at vector.cpp:12
vector`main + 1071 at vector.cpp:12
所以std::vector<int>
的begin & end访问器的所有实例都是内联的。再往下看来自std c库本身的部分:
12 matches found in /usr/lib/libc++.1.dylib:
Address: libc++.1.dylib[0x000000000003e4ec] (libc++.1.dylib.__TEXT.__text + 252188)
Summary: libc++.1.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::begin() Address: libc++.1.dylib[0x000000000003e51c] (libc++.1.dylib.__TEXT.__text + 252236)
Summary: libc++.1.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::begin() const Address: libc++.1.dylib[0x000000000003e574] (libc++.1.dylib.__TEXT.__text + 252324)
还有一些针对basic_string的,仅此而已。所以我们不能调用任何真正的实现。然后,一旦我们只获得了这些std对象的一小部分真实世界,当你开始推动它时,世界就会以其他奇怪的方式分崩离析。
lldb目前还不够聪明,无法弄清楚如何从C++标准库的头文件中重构模板化的函数/方法。我们没有足够的环境,您的代码最初被编译来完成这项任务。
请注意,这实际上不是重载操作符的问题,而是编译器使用std库的方式的问题。对于您自己的类来说,事情应该运行得更好,在-O0中没有那么多内联。
https://stackoverflow.com/questions/20387942
复制相似问题