Verschiedene Probleme mit std::atomic_init


  • Mod

    Ich habe gerade mal ein bisschen mit den atomics rumgespielt, Compiler ist GCC 4.8:

    Erstes Problem:
    Wie nutze ich atomic_init richtig?

    #include <vector>
    #include <atomic>
    
    int main()
    {
      std::vector<std::atomic<int>> numbers(5);
    
      for(int i = 0; i < 5; ++i)
        std::atomic_init(&numbers[i], i);
    }
    

    Das gibt mir:

    In file included from test.cc:2:0:
    /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/atomic:807:5: warning: inline function ‘void std::atomic_init(std::atomic<_ITp>*, _ITp) [with _ITp = int]’ used but never defined [enabled by default]
         atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
         ^
    /tmp/ccuBLH8i.o: In function `main':
    test.cc:(.text.startup+0x40): undefined reference to `void std::atomic_init<int>(std::atomic<int>*, int)'
    collect2: error: ld returned 1 exit status
    

    Muss ich hier noch irgendwas zusätzlich zur Standardbibliothek dazulinken? Ich habe vage Hinweise auf so etwas in der GCC-Wiki gefunden, aber eigentlich stand da auch, dass dies bei 4.8 nicht mehr nötig wäre und wie die Bibliothek heißen sollte, habe ich auch nicht finden können.

    Zweites Problem:
    Ernsthaft, wie benutzt man std::atomic_init?

    int main()
    {
      std::vector<std::atomic_int> numbers(5);
    
      for(int i = 0; i < 5; ++i)
        std::atomic_init(&numbers[i], i);
    }
    

    Gibt mir

    test.cc: In function ‘int main()’:
    test.cc:9:36: error: no matching function for call to ‘atomic_init(__gnu_cxx::__alloc_traits<std::allocator<std::__atomic_base<int> > >::value_type*, int&)’
         std::atomic_init(&numbers[i], i);
                                        ^
    test.cc:9:36: note: candidates are:
         std::atomic_init(&numbers[i], i);
                                        ^
    In file included from test.cc:2:0:
    /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/atomic:807:5: note: template<class _ITp> void std::atomic_init(std::atomic<_ITp>*, _ITp)
         atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
         ^
    /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/atomic:807:5: note:   template argument deduction/substitution failed:
         atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
         ^
    test.cc:9:36: note:   ‘__gnu_cxx::__alloc_traits<std::allocator<std::__atomic_base<int> > >::value_type {aka std::__atomic_base<int>}’ is not derived from ‘std::atomic<_ITp>’
         std::atomic_init(&numbers[i], i);
                                        ^
    In file included from test.cc:2:0:
    /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/atomic:811:5: note: template<class _ITp> void std::atomic_init(volatile std::atomic<_ITp>*, _ITp)
         atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
         ^
    /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../include/c++/4.8.0/atomic:811:5: note:   template argument deduction/substitution failed:
         atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
         ^
    test.cc:9:36: note:   ‘__gnu_cxx::__alloc_traits<std::allocator<std::__atomic_base<int> > >::value_type {aka std::__atomic_base<int>}’ is not derived from ‘volatile std::atomic<_ITp>’
         std::atomic_init(&numbers[i], i);
    

    😕 std::__atomic_base<int>}’ is not derived from ‘std::atomic<_ITp>’ Aber atomic_int soll doch ein typedef auf std::atomic<int> sein! Fehler im GCC?

    Drittes Problem:
    Wozu überhaupt atomic_init?
    Wo wäre der Unterschied zu

    int main()
    {
      std::vector<std::atomic<int>> numbers(5);
    
      for(int i = 0; i < 5; ++i)
        std::atomic_store(&numbers[i], i);
    }
    

    ?
    Der letzte Code funktioniert übrigens ganz wunderbar.



  • atomic_init ist im Gegensatz zu atomic_store nicht atomar. Warum es nicht funktioniert, kann ich Dir leider nicht sagen.



  • std::atomic_int
    

    Funktioniert bei mir wunderbar mit VS 2012. Kannst du ja gern ausprobieren.


  • Mod

    knivil schrieb:

    std::atomic_int
    

    Funktioniert bei mir wunderbar mit VS 2012. Kannst du ja gern ausprobieren.

    Meinst du den Datentyp an sich (der funktioniert auch wunderbar) oder auch im Zusammenspiel mit den ganzen Funktionstemplates aus atomic (atomic_store und andere funktionieren bei mir auch nur mit std::atomic<X> statt std::atomic_X)?



  • int main()
    {
      std::vector<std::atomic_int> numbers(5); 
    
      for(int i = 0; i < 5; ++i) 
        std::atomic_init(&numbers[i], i); 
    
      return 0;
    }
    

    Dieses Programm liefert keine Fehlermeldung im Gegensatz zu

    int main()
    {
      std::vector<std::atomic<int>> numbers(5);
    
      for(int i = 0; i < 5; ++i)
        std::atomic_init(&numbers[i], i);
    }
    

    Kann sein, dass der seperate Typ mehr bietet als std::atomic<int>, obwohl es nur ein typdef sein sollte. Ich bin der Sache aber nicht nachgegangen. Komplette Fehlermeldung:

    1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xutility(2466): error C2248: 'std::atomic<int>::operator =' : cannot access private member declared in class 'std::atomic<int>'
    1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xxatomic(279) : see declaration of 'std::atomic<int>::operator ='
    1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xxatomic(254) : see declaration of 'std::atomic<int>'
    1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xutility(2487) : see reference to function template instantiation '_OutIt std::_Move<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_Nonscalar_ptr_iterator_tag)' being compiled
    1>          with
    1>          [
    1>              _OutIt=std::atomic<int> *,
    1>              _InIt=std::atomic<int> *
    1>          ]
    1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\vector(1402) : see reference to function template instantiation '_OutIt std::_Move<std::atomic<int>*,std::atomic<int>*>(_InIt,_InIt,_OutIt)' being compiled
    1>          with
    1>          [
    1>              _OutIt=std::atomic<int> *,
    1>              _InIt=std::atomic<int> *
    1>          ]
    1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\vector(1381) : while compiling class template member function 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Myvec>,std::_Vector_const_iterator<_Myvec>)'
    1>          with
    1>          [
    1>              _Myvec=std::_Vector_val<std::_Simple_types<std::atomic<int>>>,
    1>              _Ty=std::atomic<int>
    1>          ]
    1>          test move.cpp(13) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
    1>          with
    1>          [
    1>              _Ty=std::atomic<int>
    1>          ]
    

Anmelden zum Antworten