Strategia per OS X e versione precedente della libreria C ++ 11?

5

Penso di essermi trovato in una situazione in cui le cose stanno rapidamente andando fuori controllo e vorrei ricevere un feedback per selezionare un modo per procedere.

SFONDO

Sto lavorando con una libreria basata su C ++ 03. La libreria è multipiattaforma e supporta più compilatori. Non ci sono dipendenze o prerequisiti esterni (ad esempio, non è necessario per Autotools, Cmake, Boost, ecc.). Abbiamo iniziato a testare con std=c++11 e abbiamo trovato alcune cose da correggere. Ad esempio, auto_ptr è stato deprecato, quindi abbiamo dovuto passare a unique_ptr se __cplusplus >= 201103L .

Il passaggio a unique_ptr è stato relativamente facile, tranne su OS X. OS X pubblicizza __cplusplus come 201103L , ma è una libreria di runtime C ++ 11 estremamente carente (non ho intenzione di usare il parola "standard" in quella frase). Peggio ancora, se qualcuno costruisce l'ultimo LLVM / Clang da sorgenti su OS X senza libcxx , allora esistono le stesse carenze perché il nuovo Clang usa le vecchie librerie.

Per risolvere il problema di auto_ptr , siamo passati attraverso alcuni cerchi che terminavano con il seguente codice. Mentre il codice sotto sembra pulito, il preprocessore sta funzionando fuori orario per determinare quando deve definire MYLIB_HAVE_UNIQUE_PTR e MYLIB_HAVE_TEMPLATE_ALIAS a causa di OS X.

// The result is MyLib::auto_ptr in both cases
#if defined(MYLIB_HAVE_UNIQUE_PTR) && defined(MYLIB_HAVE_TEMPLATE_ALIAS)
  template<typename T>
    using auto_ptr = std::unique_ptr<T>;
#else
  using std::auto_ptr;
#endif

Stiamo ora cercando di fornire semantica di spostamento protetta su __cplusplus perché ci sono da due a cinque classi che potrebbero trarne vantaggio. Tuttavia, OS X ci sta dando di nuovo problemi perché manca std::move . Sospetto che abbia anche problemi con Rvalues e Rvalue References.

Abbiamo chiesto agli sviluppatori di Clang come eseguire il test delle funzioni per std::move in How per testare std :: move (intersezione di Apple e Clang) . Uno degli sviluppatori di Clang ha suggerito di lanciare il nostro, ma sto iniziando a pensare che sia una battaglia persa basata sul codice sorgente di GNU per move.h . Ad esempio, una rapida grep -IR is_lvalue_reference /usr/include/c++/4.2.1/ non rivela hit.

STRATEGIE

Penso che le nostre scelte siano (1) eliminare del tutto il supporto per OS X; (2) tratta OS X come C ++ 03; (3) implementare la nostra implementazione per le funzionalità mancanti di C ++ 11 su OS X; oppure (4) passare ad Autotools o Cmake per il rilevamento delle funzioni.

(1) non sta per accadere categoricamente. (2) sembra ragionevole. (3) sembra un sacco di lavoro. (4) non accadrà perché introduce delle dipendenze esterne.

Per (2), credo che il test sia facile come:

//  For Microsoft's cl.exe, pivot on _MSC_VER, not __cplusplus.
#if (_MSC_VER >= 1600) || (__cplusplus >= 201103L)
# define MYLIB_CXX11 1
#endif

// Ancient C++ runtime library; unset it because its too much trouble.
// Thanks to Jonathan Wakely for the '__has_include(<forward_list>)'
//     test. See http://stackoverflow.com/q/31655462.
// TODO: test under Xcode 3, where g++ is really g++.
#if defined(__clang__)
#    if !(__has_include(<forward_list>))
#        undef MYLIB_CXX11
#    endif
#endif

Quindi torna al rilevamento delle caratteristiche canonizzate:

#if MYLIB_CXX11

  // Everyone appears to provide this list
  #define MYLIB_CXX11_UNIQUE_PTR 1
  ...

  // template aliases: MS at VS 2015 (v19.00); GCC at 4.7; Clang at 3.0; and Intel 12.1.
  #if (_MSC_VER >= 1900) || (__INTEL_COMPILER >= 1210)
  #  define MYLIB_CXX11_TEMPLATE_ALIAS 1
  #elif defined(__clang__)
  #  if (__has_feature(cxx_alias_templates))
  #    define MYLIB_CXX11_TEMPLATE_ALIAS 1
  #  endif
  #elif (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
  #  define MYLIB_CXX11_TEMPLATE_ALIAS 1
  #endif // template aliases

#endif // MYLIB_CXX11

DOMANDE

Esistono altre strategie per gestire C ++ 11 e OS X?

Qualcuno ha provato la strategia (3)? Se sì, quanto lavoro è stato?

testing

Se hai accesso a OS X, prova a seguire il compilatore incorporato, lo standard e libstdc++ di GNU rispetto a libc++ di LLVM. Successivamente, prova con un compilatore moderno esportando CXX=/opt/local/bin/clang++ .

$ cat test-clapple.cxx

// c++ -c test-clapple.cxx
// c++ -stdlib=libc++ -c test-clapple.cxx
// c++ -std=c++11 -c test-clapple.cxx
// c++ -std=c++11 -stdlib=libc++ -c test-clapple.cxx

# include <memory>

// Manage auto_ptr warnings and deprecation in C++11
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900)
  template<typename T>
    using auto_ptr = std::unique_ptr<T>;
#else
    using std::auto_ptr;
#endif // C++11

int main(int argc, char* argv[])
{
    return argc;
}
    
posta jww 02.08.2015 - 02:00
fonte

1 risposta

3

Non è MacOSX, è il compilatore che usi su di esso.

Quindi, semplicemente aggiorna il tuo compilatore , forse costruendo da il loro codice sorgente a recente versione di Clang / LLVM e / o GCC compiler (s).

(non hai bisogno dell'autorizzazione di Apple per compilare e utilizzare un compilatore più recente. Devi solo prendere tempo per leggere e seguire le istruzioni di compilazione, in poche ore puoi ottenere l'ultima versione di GCC o di Clang in esecuzione sul tuo computer)

A dicembre 2015, l'attuale GCC è GCC 5.3 e l'attuale Clang è Clang 3.7 ; e potresti configurarli in modo che il compilatore venga chiamato g++-mine o clang++-mine se lo desideri.

    
risposta data 09.12.2015 - 22:06
fonte

Leggi altre domande sui tag