Ce que tu demandes à Laurent c'est de distribuer des binaires C++03 et des binaires C++11 ? Je doute qu'il accepte :o
Non, c'est ça qui est marrant: ce qui est possible, c'est de compiler la SFML en C++11 et de laisser le choix à l'utilisateur d'utiliser les nouvelles fonctionalités ou non (ou tout simplement parce que son compilateur ne le supporte pas).
Un petit exemple rapide. Laurent, tu me dis si un pull qui ressemblerai à ça serait accepté ;)
Imaginons que je compile ma librairie libtest.so pour supporter ET le C++11 ET les anciennes versions. Voilà le contenu des fichiers:
Test.hpp
#ifndef TEST_HPP
#define TEST_HPP
struct Test
{
Test();
~Test();
Test(const Test&);
Test& operator=(const Test&);
#ifdef USE_RREF // aha!
Test(Test&&);
Test& operator=(Test&&);
#endif
};
#endif // TEST_HPP
Test.cpp
#include <iostream>
#include "Test.hpp"
using namespace std;
Test::Test()
{
cout << "default constructor" << endl;
}
Test::Test(const Test&)
{
cout << "copy constructor" << endl;
}
#ifdef USE_RREF // re- aha!
Test::Test(Test&&)
{
cout << "move constructor" << endl;
}
#endif
Test::~Test()
{
cout << "destructor" << endl;
}
Test& Test::operator=(const Test&)
{
cout << "operator= copy" << endl;
return *this;
}
#ifdef USE_RREF
Test& Test::operator=(Test&&)
{
cout << "operator= move" << endl;
return *this;
}
#endif
Ici, on peut choisir de supporter au non les constructeurs de mouvement.
Compilons la lib avec ce nouveau support (sans oublier d'utiliser C++11 ;) ):
g++ -shared Test.cpp Test.hpp -DUSE_RREF -std=c++11 -o libtest.so
Après, le code utilisateur pourra choisir d'utiliser les nouvelles fonctionalitées ou non:
main.cpp
#include <Test.hpp>
#include <iostream>
using namespace std;
int main()
{
Test t1;
t1 = Test();
return 0;
}
me:~/projects/tests$ mv libtest.so ~/home/me/bin
me:~/projects/tests$ g++ main.cpp -I. -L/home/me/bin -ltest -o sans_rvalue
me:~/projects/tests$ g++ main.cpp -I. -L/home/me/bin -ltest -o avec_rvalue -std=c++11 -DUSE_RREF
me:~/projects/tests$ ./sans_rvalue
default constructor
default constructor
operator= copy
destructor
destructor
me:~/projects/tests$ ./avec_rvalue
default constructor
default constructor
operator= move // Le constructeur de copie n'est ici plus utilisé
destructor
destructor
Et avec la seule librairie compilée en C++11 ;)
Après il peut être encore meilleur de détecter automatiquement si le compilateur supporte les nouvelles fonctionalités désirées, sans que l'utilisateur n'ai rien à définir :)
Oui si on change un attribut entre le header et la source ça peut poser des soucis... Je ne pense pas que ce passerait à l'édition des liens.
Car une fois cette étape passée, je ne suit pas sûr qu'un bug soit possible.
Je pense que tu as mal compris ce que j'ai expliqué :P
Comme on n'a pas d'exemple concret avec du C++11, je vais utiliser un exemple qui montre le problème entre binaires debug et release avec Visual C++, et qui est exactement le même problème.
Imagine une telle classe :
class Blop
{
std::vector<int> v;
};
Assez anodine en apparence.
Mais si tu regardes la définition de la classe std::vector, tu vois un truc dans ce genre (ne prends pas ça à la lettre, c'est pour illustrer):
template <typename T, typename Allocator = std::allocator<T> >
class vector
{
#ifdef _MACRO_DE_DEBUGGING_ALACON
Pouet debug_data;
#endif
T* data;
size_t size;
};
Ensuite tu compiles ta bibliothèque en release: la classe Blop est donc composée d'un vecteur lui-même composé d'un pointeur et d'une taille. sizeof(Blop) == 8 (sur architecture 32 bits). En outre, pour accéder au membre "data" du vecteur, le compilateur applique un offset de 0 sur "this".
Puis, tu utilises cette bibliothèque mais en mode debug. Du coup le compilateur prend la définition du vecteur contenant les debug_data, et du coup sizeof(Blop) > 8. En outre, pour accéder au membre "data" du vecteur, le compilateur applique un offset de sizeof(Pouet) sur "this".
Puis vient l'étape finale : tu crées un Blop via ton code, puis refourgue son adresse à ta bibliothèque. Comme c'est ton code qui l'a créé, il a un membre debug_data et son pointeur vers les données se trouve à l'offset sizeof(Pouet). Mais comme ta lib a été compilée avec une version de std::vector dont le pointeur se trouve à l'offset 0... lorsque ta lib utilise cette instance de Blop... ça pète, elle accède en réalité à des bits appartenant à "debug_data".
Voilà :P
Afin de pouvoir utiliser les Vector en atomic j'ai dût les rendre POD, je pense que c'est une modification assez indispensable pour une adaptation c++11. ^^
// Vector2();
Vector2() = default;
Vector2(T X, T Y);
...
// T x; ///< X coordinate of the vector
// T y; ///< Y coordinate of the vector
T x = 0; ///< X coordinate of the vector
T y = 0; ///< Y coordinate of the vector