[pull request] - platform.h - proposal of fixing platform detection issues

9 views
Skip to first unread message

Paweł Głodny R.

unread,
Jan 18, 2017, 3:20:01 AM1/18/17
to g3d-dev...@googlegroups.com
ISSUE
=====

G3D10 >= trunk
CLang >= 3.9
"std::shared_ptr" vs "std::tr1::shared_ptr"

When compiling G3D10 "trunk" version on fresh platform I've got issues with proper c++ version detection here on clang.
Basically there was confusion between "std::shared_ptr" and "std::tr1::shared_ptr" with "createShared<>()".

Example:

In file included from include/G3D/ParseOBJ.h:25:
include/G3D/ParseMTL.h:140:11: error: no viable conversion from returned value of type 'std::shared_ptr<Material>' to function return type 'shared_ptr<G3D::ParseMTL::Material>' (aka 'std::tr1::shared_ptr<G3D::ParseMTL::Material>')
                        return createShared<Material>();
                               ^~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/tr1/shared_ptr.h:983:11: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::shared_ptr<Material>' to 'const std::tr1::shared_ptr<G3D::ParseMTL::Material> &' for 1st argument
    class shared_ptr
          ^


FIX
===

It was because my platform configuration did not have <ciso646> include file.
Simple script to check <ciso646> and _LIBCPP_VERSION stuff: 

printf "#include <ciso646>\nint main () {}" | clang -E -stdlib=libc++ -x c++ -dM - | grep _LIBCPP_VERSION

I've done some digging and the c++11 check can (should) be made independent from <ciso646> to support more configurations.

Basic check:

#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600)

should work for all recent GNU/CLang/MSVC platform configurations.
It certainly worked for me, but i have no way of checking on MacOS or Windows.

There can be some rare cases when, despite having new compiler, platform uses "ancient" libc++ or libstdc++ version. In such cases checking explicitly for available includes should do the trick, example:

#   if __has_include(<forward_list>)
// either using libc++ or a libstdc++ that's new enough to have unique_ptr

Or we can then check with <ciso646> in that case too.

Some StackExchange threads:



DIFF
====

(glodny) - (jobs:0) - (~/projects/code/_lib/g3d/G3D10) -  svn trunk
 --> svn diff G3D.lib/include/G3D/platform.h 


Index: G3D.lib/include/G3D/platform.h
===================================================================
--- G3D.lib/include/G3D/platform.h (wersja 1042)
+++ G3D.lib/include/G3D/platform.h (kopia robocza)
@@ -361,10 +361,22 @@
 
 
 // Bring in shared_ptr and weak_ptr
-#if (defined(__GNUC__) && defined(__APPLE__)) || defined(__linux__)
-#include <ciso646> // Defines _LIBCC_VERSION if linking against libc++ or does nothing
-#endif
-#if (!defined(_LIBCPP_VERSION) && defined(__APPLE__)) || (!defined(_LIBCPP_VERSION) && defined(__linux__))
+// #if (defined(__GNUC__) && defined(__APPLE__)) || defined(__linux__)
+// #include <ciso646> // Defines _LIBCC_VERSION if linking against libc++ or does nothing
+// #endif
+
+#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600)
+//#if ((__cplusplus >= 201103L) || (_MSC_VER >= 1600)) || (__has_include(<forward_list>))
+// the check "__has_include(<forward_list>)" should be (?) enough to tell if configuration supports required c++11 features
+//# pragma message "C++11"
+#   include <memory>
+    using std::shared_ptr;
+    using std::weak_ptr;
+    using std::dynamic_pointer_cast;
+    using std::static_pointer_cast;
+    using std::enable_shared_from_this;
+#else
+//# pragma message "C++03"
 #   include <tr1/memory>
     using std::tr1::shared_ptr;
     using std::tr1::weak_ptr;
@@ -371,15 +383,9 @@
     using std::tr1::dynamic_pointer_cast;
     using std::tr1::static_pointer_cast;
     using std::tr1::enable_shared_from_this;
-#else
-#   include <memory>
-    using std::shared_ptr;
-    using std::weak_ptr;
-    using std::dynamic_pointer_cast;
-    using std::static_pointer_cast;
-    using std::enable_shared_from_this;
 #endif
 
+
 namespace G3D {
     /** Options for initG3D and initGLG3D. */
     class G3DSpecification {



Reply all
Reply to author
Forward
0 new messages