Closed elliotwoods closed 10 years ago
I'd start with this interesring if statement: #if (_MSC_VER || true)
;-) you can never enter the else clause.
also, pinging @leocolomb about this, I think he was the author of this passage.
edit: wait, what? hmmm
:) that's the bit i hacked basically the VS2012 code seems to be proper C++11, whilst the rest is using tr1 therefore the switch should really be looking for C++11, not vs2012
the switch should really be looking for C++11, not vs2012
on a second look I think I agree. but wouldn't the "proper" hack be to test for C++11 instead of true? :-) also, @tgfrerer could know what's the proper course here.
shot in the dark: could be a libc++ thing? http://stackoverflow.com/questions/7016730/compiling-with-clang-using-libc-undefined-references
wait, something is iffy. in your "original" version, where's the #if __cplusplus<201103L
clause which is in current develop?
ooh! i thought i was on recent develop since yesterday. i must have missed something. trying now!
OK possibly the problem here is just the tr1/memory include, which I think needs to select for C++11. Probably like this
#if __cplusplus < 201103L
#include <tr1/memory>
#else
#include <memory>
#endif
or so.
to notes __cplusplus < 201103L == true on xcode/libc++ c++11
[EDIT] This is only true when using stdlibc++ becuase that doesn't have c++11 support. So this statement isn't entirely correct. [/EDIT]
what's the actual value of __cplusplus
?
the new code still doesn't work, also we shouldn't be using tr1
at all
#if __cplusplus<201103L
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;
using std::tr1::enable_shared_from_this;
#endif
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::tr1::const_pointer_cast;
using std::tr1::__dynamic_cast_tag;
}
still doesn't have a c++11 code path
answers here to __cplusplus: http://stackoverflow.com/questions/12865226/in-xcode-4-5-what-is-compiler-default-for-c-standard-library-and-c-lan
It could be that this worked for now (i.e. with C++11 and stdlibc++) because according to the article I linked above, "Some standard library vendors have maintained the tr1 header files for backwards compatibility. Other vendors (such as libc++, which being c++11 only, has no backwards compatibility to worry about) do not." So now that you are using libc++ this may have gotten exposed.
answers here to __cplusplus
that's not really an answer, though. what do you get when you run the program given in the accepted answer? for kicks, could you add a std::cout << __cplusplus << std::endl;
, from here?
I have to setup a separate app (oF wont run in this configuration), and the result is 201103, which tallies with what we're currently using.
to confirm, libc++ is required for using std::function.
to confirm, libc++ is required for using std::function.
you mean C++11, not libc++, right? std:function is also in stdlibc++. or is this not available on macos?
I'm sorry I can't help better, but without having macos or libc++ available, it's a bit hard to troubleshoot.
To summarize my thoughts, I think we have two (independent) issues here:
using std::tr1::static_pointer_cast;
etc. in a C++11 environment is strictly incorrect, but apparently OK when using some implementations (i.e. stdlibc++), but not others which don't provide backwards compatibility (i.e. libc++).Correct re:not available on mac os, sorry to send those emails. On XCode, libc++ is required for C++11:
To confirm:
I'll edit the bug at the top.
thanks for the follow up. I'm wondering, with
- With oF / libc++ / XCode 4 / C++11, __cpluplus == 201103L
how was this possible:?
to notes __cplusplus < 201103L == true on xcode/libc++ c++11
was there a configuration change or so between those two observations/comments?
I've updated the note above. I was getting __cplusplus == 201103L with libc++, and < 201103L with stdlibc++
I got a saner ifdef logic running nearly running on my machine now, with the exception of the dynamic_cast_tag
which does not seem to exist on C++11 anymore.
@tgfrerer, who introduced this in 77123775561a11058de33af7e9ba70c2c549abbf: what is this about, and how do we make it work on C++11/libc++? (without touching TR1 I guess) A google search primarily points back to OF code ;-) I can't find any reference to it outside of tr/shared_ptr.h.
Yep, changing the top section to:
#if (_MSC_VER || _LIBCPP_VERSION)
#include <memory>
#else
basically fixes everything except dynamic_tag
What I got currently works for me on ubuntu/stdlibc++ except the dynamic_cast_tag. If we find out why VS wants different include path in C++98, we might even be able to get rid of that, too.
#if (_MSC_VER)
#include <memory>
#else
#if __cplusplus<201103L
#include <tr1/memory>
// import smart pointers utils into std
namespace std {
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;
using std::tr1::enable_shared_from_this;
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::tr1::const_pointer_cast;
using std::tr1::__dynamic_cast_tag;
}
#else
#include <memory>
//still have to deal with __dynamic_cast_tag here!
#endif
#endif
This hack temporarily works:
#if (_MSC_VER)
template<typename Tp1>
ofPtr(const ofPtr<Tp1>& __r, std::_Dynamic_tag)
: std::shared_ptr<T>(__r, std:::_Dynamic_tag()) { }
#elif (!_LIBCPP_VERSION)
template<typename Tp1>
ofPtr(const ofPtr<Tp1>& __r, std::__dynamic_cast_tag)
: std::shared_ptr<T>(__r, std::__dynamic_cast_tag()) { }
#endif
Basically knock out the dynamic_tag bits when using LIBC
I presume there's a different approach to dynamic casting in c++11 in general.
but are you then not missing this template version/declaration on libc++, cause you get neither the MSC nor the "normal" version?
I'm guessing the C++11 way is via dynamic_pointer_cast
http://www.cplusplus.com/reference/memory/dynamic_pointer_cast/
I'm sorry about the confusion before This was because i wasn't setting the C++ dialect to C++11 :
Now it compiles, but bombs out on linking, with basically the entire standard library under complaint: https://gist.github.com/elliotwoods/6081901 (clean rebuilds don't help) Something else is going on here.
My app has the c++11 settings in the screenshot, and it doesn't matter if i compile openFrameworks with or without those flags set, i get the same linker errors (thought it might be a mismatch issue. might still be a mismatch issue with poco or something)
I add my notes, because I have been pinged:
__cplusplus == 199711L
.__cplusplus == 201103L
.With your last code, it should work with:
#if (__cplusplus<201103L && !(_MSC_VER))
#include <tr1/memory>
// import smart pointers utils into std
namespace std {
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;
using std::tr1::enable_shared_from_this;
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::tr1::const_pointer_cast;
using std::tr1::__dynamic_cast_tag;
}
#else
#include <memory>
//still have to deal with __dynamic_cast_tag here!
#endif
EDIT: Also, see this question.
dynamic_pointer_cast
allows you to cast an ofPtr from its parent type to one of its derived types, just like dynamic_cast
(which is the preferred c++ style of dynamic pointer casting) does for raw pointers.
dyamic_cast_tag
was an internal flag that some c++11 implementations used to signal that the shared ptr was going to be re-cast, and this is where it gets ugly, since some compilers/implementations used this flags, some didn't, and ofPtr, being essentially a façade around shared_ptr had to take all this into account.
in the short term, i'd suggest taking out the dynamic_pointer_cast functionality from ofPtr, since it does more bad than good, there real-life use-cases are rare and far-between, and it's proved being a maintainability nightmare.
in the long term, i'd suggest deprecating ofPtr in favour of shared_ptr and unique_ptr, since that will also give us more compatibility towards other libraries.
thanks for clearing this up @tgfrerer! So, to make your short-term fix happen, we can just rip out https://github.com/openframeworks/openFrameworks/blob/develop/libs/openFrameworks/types/ofTypes.h#L186-L194 and https://github.com/openframeworks/openFrameworks/blob/develop/libs/openFrameworks/types/ofTypes.h#L205-L216, correct? Will this break project or have other negative repercussions we should note in the release notes etc?
To confirm, would this disallow casting an ofPtr of a class to/from a parent type from/to a child type?
it would.
but then, you could always use a hack - grabbing the raw pointer from within ofPtr and re-casting that using raw pointer cast methods.
the preferred method for dynamic casting shared pointers would be to use shared_ptr instead of ofPtr in these cases, ofPtr doesn't really give you that much (apart from cross-compiler headaches) in more advanced use-cases, and with the advent of c++11 it will be much easier and future-proof to stick with the standard unique_ptr and shared_ptr.
ok understood. can we therefore rewrite ofPtr for c++11 to wrap shared_ptr?
ofPtr already wraps shared_ptr =) but it's this wrapping - or better put: the façade design pattern - that causes the complications.
i think ofPtr was introduced to have a compiler and c++ version independent wrapper around shared_ptr. But now that shared_ptr has become part of the standard, why not use the real thing?
it was even just to make it more of'ish :) i'm totally ok with removing it once we have compatibility with c++11 and use the standard. meanwhile can we perhaps deactivate the dynamic casting hack for vs on c++11 so people can still use c++11 on that platform
i guess an ifdef around that code will do
On 08/05/2013 03:50 PM, Tim Gfrerer wrote:
ofPtr already wraps shared_ptr =) but it's this wrapping - or better put: the façade design pattern - that causes the complications.
i think ofPtr was introduced to have a compiler and c++ version independent wrapper around shared_ptr. But now that shared_ptr has become part of the standard, why not use the real thing?
— Reply to this email directly or view it on GitHub https://github.com/openframeworks/openFrameworks/issues/2335#issuecomment-22107100.
=) let's do it.
C++11 works fine with VS and oF right now. Xcode is issue here
oh, ok, osx then :)
On 08/05/2013 04:01 PM, Elliot Woods wrote:
C++11 works fine with VS and oF right now. Xcode is issue here
Typed by touchscreen
On 5 Aug 2013, at 14:59, arturo notifications@github.com wrote:
it was even just to make it more of'ish :) i'm totally ok with removing it once we have compatibility with c++11 and use the standard. meanwhile can we perhaps deactivate the dynamic casting hack for vs on c++11 so people can still use c++11 on that platform
i guess an ifdef around that code will do
On 08/05/2013 03:50 PM, Tim Gfrerer wrote:
ofPtr already wraps shared_ptr =) but it's this wrapping - or better put: the façade design pattern - that causes the complications.
i think ofPtr was introduced to have a compiler and c++ version independent wrapper around shared_ptr. But now that shared_ptr has become part of the standard, why not use the real thing?
— Reply to this email directly or view it on GitHub < https://github.com/openframeworks/openFrameworks/issues/2335#issuecomment-22107100>.
— Reply to this email directly or view it on GitHubhttps://github.com/openframeworks/openFrameworks/issues/2335#issuecomment-22107615
.
— Reply to this email directly or view it on GitHub https://github.com/openframeworks/openFrameworks/issues/2335#issuecomment-22107812.
+1 on getting rid of ofPtr
in favour of shared_ptr
if it is possible.
For someone new to oF and on a c++ learning curve, ofPtr is a bit shrouded in mystique without much accessible info (the philosophy behind it, how it works or why it's there). shared_ptr
on the other hand is highly googleable.
any updates on this issue?
+1 to get this moving. Even if we aren't going to immediately remove ofPtr
it would be really nice to get some preprocessor help to get the core / projects to compile c++11 running in the core easily.
+1 Had the same issue with gcc in linux trying to use c++11 features not included in tr1 (like thread which is a super clean way to multithread functions). Got it working by eliminating dynamic_cast_tag, but it would be convenient to have a preprocessor flag to allow c++11 to work. I'll also second removing ofPtr in favor of shared_ptr. Using std library just seems better when possible.
could we just typedef ofPtr to shared_ptr?
On 12 September 2013 10:48, Jesse Louis-Rosenberg notifications@github.comwrote:
+1 Had the same issue with gcc in linux trying to use c++11 features not included in tr1 (like thread which is a super clean way to multithread functions). Got it working by eliminating dynamic_cast_tag, but it would be convenient to have a preprocessor flag to allow c++11 to work. I'll also second removing ofPtr in favor of shared_ptr. Using std library just seems better when possible.
— Reply to this email directly or view it on GitHubhttps://github.com/openframeworks/openFrameworks/issues/2335#issuecomment-24289787 .
Elliot Woods elliot elliot@kimchiandchips.com@KimchiAndChips.comhttp://www.kimchiandchips.com/
It's hard (if not impossible) to typedef a template.
The next idea would be to use a preprocessor macro to substitute any mentions of ofPtr with shared_ptr, but this also is not un-tricky.
That said, if there was common interest in getting c++11 to run, how about we get together and make a branch (and ultimately a PR) where we concentrate our efforts (and findings)?
forgive my ignorance, but something like this is not an option? Also, might as well wrap ofPtr in a deprecation macro at the same time, if we want to phase it out anyway.
can somebody explain why we made ofPtr in the first place? it seems that there is a a little bit of confusion as to why it exists
it looks prettier than shared_ptr
, which I think is the only reason i use it.
On that Stack Overflow post:
The catch is that nobody supports it yet. GCC has a patch available, but it probably won't make it into mainline until 4.7.
that was in 2011 (it's a C++0x feature)
I presume that compilers in the C++11 regime will be fine with it, if so, we could switch to template alias for C++11 compilers, and stick with existing tr1 implementation for previous?
@elliotwoods as @arturoc explains earlier, it was made to make shared pointers more "oF-ish": https://github.com/openframeworks/openFrameworks/issues/2335#issuecomment-22107615
@bilderbuchi The key would be to make things simpler, and more standards-compliant, which is why I'm strongly in favour of ditching ofPtr. I fear the stackoverflow method adds another layer of "wrapping paper," which we don't really need.
The current problem with ofPtr imho is that it's a cross compiler maintenance headache waiting to happen, and not compatible with standards-compliant APIs that use shared_ptr. In short: it is complicated code where it doesn't need to be.
cheers @tgfrerer
what i've learned from this thread:
Don't use ofPtr it's bad for business
Hey all!
[EDIT] It seems that we don't have c++11 support right now with on osx. The issue primarily is that we have to use libc++ with c++11, which does not support legacy tr1 namespace symbols. To fix this bug we need to write a c++11 version which does not use tr1 namespace.
This could either involve:
I think the only difference between 1 and 2 is more testing is required for 1. (i.e. the code should look identical).
[/EDIT]
In ofTypes I edited:
to:
now i get complaints on
__dynamic_cast_tag
. And ran out of google results. ideas?