2014-10-30 15 views
6

Próbuję nowych funkcji C++ 11 i znalazłem problem. To jest mój kod:błąd na g ++ 4.8.2 na liście metoda-argument inicjalizacja domyślna

#include <iostream> 
#include <list> 
#include <string> 

using namespace std; 

class A { 
public: 
     int f (list<string> a, list<string> b={}) 
     { 
      cout << a.size() << endl; 
      cout << b.size() << endl; // This line!!! 
      return 0; 
     } 
}; 

int main() 
{ 
    A a; 
    list<string> l{"hello","world"}; 
    a.f(l); 
    return 0; 
} 

Egzekucja utknęła na "tej linii !!!" linia. Kontynuuję debugowanie i wygląda na to, że problem jest tutaj.

 /** Returns the number of elements in the %list. */ 
     size_type 
     size() const _GLIBCXX_NOEXCEPT 
     { return std::distance(begin(), end()); } 

skompilować mój program w ten sposób:

g++ -std=c++11 -ggdb3 -fPIC -o test TestlistInit.cpp 

używam tej wersji g ++:

g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2 

góry dzięki !!!

+3

Mam ten sam problem w wersji 4.7.3, co ciekawe po prostu zastępuję 'list b = list ()' działa. Ale tak, wygląda na bug gcc. – Barry

+2

Zdecydowanie błąd. Otrzymujesz błąd segmentacji (http://coliru.stacked-crooked.com/a/b1764458721a56fc) po zwróceniu go z funkcji jako domyślny argument. I zobacz, co się dzieje [gdy lista zawiera elementy.] (Http://coliru.stacked-crooked.com/a/fa7a009908546074) – 0x499602D2

+0

niesamowite, że takie podstawowe błędy są nadal w 4.8.2 ... – Walter

Odpowiedz

2

Aby znaleźć przyczynę, włącz symbole debugowania, a kiedy dojdziesz do pierwszego wiersza, najpierw sprawdzamy zawartość b, która wygląda tak (wartość będzie inna) W tym przypadku użyłem Code :: Blocks "Watch " opcja.

b.M_Impl._M_node._M_next = 0x7fffffffe370 
b.M_Impl._M_node._M_prev = 0x7fffffffe370 

Następnie użyj opcji debuggera, aby "wkroczyć", gdy uderzymy w naszą linię b.size.

Ostatecznie to zajmie nam stl_iterator_base_funcs.h

Na początku widzimy pierwszy & ostatni są takie same:

__first._M_node = 0x7fffffffe370 
__last._M_node = 0x7fffffffe370 

while (__first != __last) 
{ 
    ++__first; 
    ++__n; 
} 

Wkraczającego ++__first widzimy, robi to w stl_list.h:

_Self& 
operator++() 
{ 
_M_node = _M_node->_M_next; 
return *this; 
} 

_M_node ii _M_node->_M_next są jednakowe, więc brak __first zawsze wzrasta, a .size() jest przechwytywany w nieskończonej pętli.