L’un de mes principaux griefs à propos du C ++ est qu’il est difficile en pratique de faire passer des objets de bibliothèque std en dehors des limites de la bibliothèque dynamique (c'est-à-dire dll / so).
La bibliothèque std est souvent en-tête uniquement. Ce qui est génial pour faire des optimisations géniales. Cependant, pour les dll, elles sont souvent construites avec des paramètres de compilateur différents qui peuvent avoir un impact sur la structure / le code interne des conteneurs d'une bibliothèque std. Par exemple, dans MSVC, une dll peut être générée avec le débogage itérateur, alors qu'une autre est générée avec elle. Ces deux dll peuvent rencontrer des problèmes lors de la transmission de conteneurs std. Si j'expose std::string
dans mon interface, je ne peux pas garantir que le code utilisé par le client std::string
correspond exactement à celui de ma bibliothèque std::string
.
Cela conduit à des problèmes difficiles à résoudre, des maux de tête, etc. Vous pouvez soit contrôler de manière rigide les paramètres du compilateur dans votre organisation pour éviter ces problèmes, soit utiliser une interface C plus simple qui ne les aura pas. Ou spécifiez à vos clients les paramètres de compilateur attendus qu'ils doivent utiliser (ce qui est inutile si une autre bibliothèque spécifie d'autres paramètres de compilateur).
Ma question est de savoir si C ++ 11 a essayé de faire quelque chose pour résoudre ces problèmes?
DLL
s. EntreSO
les deux, ça a toujours bien fonctionné.Réponses:
Vous avez raison de dire qu’il est préférable d’éviter tout élément STL (en fait, tout élément d’une bibliothèque tierce qui est basée sur un modèle) dans une API C ++ publique. Vous souhaitez également suivre la longue liste de règles sur http://www.ros.org/reps/rep-0009.html#definition pour empêcher la rupture ABI, ce qui fait de la programmation des API C ++ publiques une corvée.
Et la réponse concernant C ++ 11 est non, cette norme ne touche pas cela. Plus intéressant, pourquoi pas? La réponse est parce que C ++ 17 est très touchant et que, pour que les modules C ++ soient implémentés, nous avons besoin de modèles exportés pour fonctionner, et pour cela, nous avons besoin d’un compilateur de type LLVM, tel que clang, capable de transférer tout l’AST sur disque, puis Effectuez des recherches, en fonction de l'appelant, pour traiter les nombreux cas de violation de l'ODR dans tout grand projet C ++ - qui, par ailleurs, inclut beaucoup de code GCC et ELF.
Enfin, je vois beaucoup de commentaires haineux et de commentaires pro-GCC de MSVC. Celles-ci sont très mal informées - GCC sur ELF est fondamentalement, et irrémédiablement, incapable de produire du code C ++ valide et correct. Les raisons à cela sont nombreuses et légion, mais je citerai rapidement un exemple: GCC sur ELF ne peut pas produire en toute sécurité des extensions Python écrites à l'aide de Boost.Python, où plusieurs extensions basées sur Boost.Python sont chargées dans Python. En effet, ELF avec sa table de symboles C globale n’est tout simplement pas capable, par sa conception, de prévenir les violations ODR causant des segfaults, alors que PE et MachO et même la spécification proposée pour les modules C ++ utilisent tous des tables de symboles par module, ce qui signifie aussi des temps d’initialisation du processus beaucoup plus rapides. Et il y a beaucoup plus de problèmes: voir un StackOverflow auquel j'ai répondu récemment àhttps://stackoverflow.com/questions/14268736/symbol-visibility-exceptions-runtime-error/14364055#14364055 par exemple, lorsque les levées d'exceptions C ++ sont irrémédiablement brisées sur ELF.
Dernier point: en ce qui concerne l’interopérabilité de différents STL, c’est un gros problème pour de nombreuses grandes entreprises qui essaient de mélanger des bibliothèques tierces étroitement intégrées à certaines implémentations de STL. La seule solution est un nouveau mécanisme permettant au C ++ de gérer l'interopérabilité STL. Vous pouvez également réparer l'interopérabilité du compilateur pour pouvoir, par exemple, mélanger des fichiers objet compilés MSVC, GCC et Clang, et tout fonctionne. . Je regarderais les efforts de C ++ 17 et verrais ce qui se passera dans les prochaines années - je serais surpris que rien ne se produise.
la source
La spécification n'a jamais eu ce problème. En effet, le concept appelé "règle de définition unique" stipule que chaque symbole a exactement une définition dans le processus en cours.
Les DLL Windows violent cette exigence. C'est pourquoi il y a tous ces problèmes. C'est donc à Microsoft de le réparer, et non au comité de normalisation C ++. Unix n’a jamais eu ce problème, car les bibliothèques partagées fonctionnent différemment ici et sont conformes par défaut à une règle de définition (vous pouvez explicitement le casser, mais vous ne le faites évidemment que si vous savez que vous pouvez vous le permettre et que vous devez extraire les quelques cycles supplémentaires).
Les DLL Windows violent une règle de définition pour les raisons suivantes:
Unix utilisant les exportations au format ELF importe implicitement tous les symboles exportés pour éviter le premier problème et ne fait pas la distinction entre les symboles résolus statiquement et dynamiquement avant le temps de liaison statique pour éviter le second.
L'autre problème concerne les drapeaux du compilateur. Ce problème existe pour tout programme composé de plusieurs unités de compilation, les bibliothèques dynamiques ne doivent pas être impliquées. Cependant, c'est bien pire sous Windows. Sous Unix, peu importe que vous liez statiquement ou dynamiquement, personne ne lie le runtime standard de toute façon (sous Linux, cela peut même être illégal) et il n’existe aucun runtime de débogage spécial, une construction est donc suffisante. Mais la manière dont Microsoft a implémenté les liaisons statiques et dynamiques, les applications de débogage et d’exécution ainsi que certaines autres options a provoqué une explosion combinatoire des variantes de librairies nécessaires. Là encore, problème de plate-forme plutôt que de langage C ++.
la source
Non.
Il y a beaucoup de travail en cours pour remplacer le système d'en-tête, une fonctionnalité appelée Modules et qui pourrait avoir un impact sur cela, mais certainement pas une grosse.
la source