簡體   English   中英

在c ++ lldb中使用重載運算符計算表達式

[英]Evaluating an expression with overloaded operators in c++ lldb

我正在使用lldb在Xcode 5中調試C ++程序,我想在調試器中評估任意表達式,特別是那些使用重載運算符的表達式。

例如,我創建了一個非常簡單的Xcode 5 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;上設置斷點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是否支持使用重載運算符進行評估?

先感謝您!

我剛遇到同樣的問題,顯然找到了一個簡單的解決方法。 你可以像這樣訪問矢量veci個元素:

(lldb) p vec.__begin_[i]
(int) $1 = 100

請注意,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>的開始和結束訪問器的所有實例都是內聯的。 更進一步來自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,而這就是全部。 所以我們沒有任何真正的實現可以調用。 然后,一旦我們只得到了我們可用的這些標准物體的真實世界,當你開始推動它時,世界就會以其他奇怪的方式崩潰。

lldb目前還不夠聰明,無法弄清楚如何從C ++標准庫的頭文件中重構模板化的函數/方法。 我們沒有足夠的代碼最初編譯的環境來執行該任務。

請注意,這對於重載運算符來說並不是一個問題,編譯器使用std庫的方式更是一個問題。 事情應該對你自己的課程更好,在-O0沒有那么多的內聯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM