-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error when compiling with clang with -std=c++11 -stdlib=libc++ #73
Comments
In c++11, the std::vector methods erase and insert take const_iterators instead of iterators, and for some reason automatic conversion does not work. In any case, one way to fix this is to change this accordingly in the file std_container.i. I also needed to compile with -Wno-c++11-narrowing to avoid errors of the kind:
While easy to fix, I couldn't find where the latter code snippet is generated from. |
I changed that rather icky code to simply use the standard |
Yes, thanks, I just updated to 2.0.11 and the latter error is indeed fixed. But in std/std_container.i the member functions erase and insert do need to be changed to take const_iterators for c++11, no? |
@ojwb indeed, compiling with llvm's libc++ the insert function will fail |
I've put the first steps towards a fix on my branch I've seen a few segfaults (which I've not yet been able to debug) in tests, but at least it's a step forward. |
This is challenging as the signature of the erase and insert methods have changed and I do not want to add some sort of c++11 command line option when running SWIG to differentiate between standards. I have just discovered the value of __cplusplus is set to 201103L for C++11, which is excellent news because there is then a standard way to detect when running in C++11 or earlier mode.
Either we use this macro to handle the difference in some way. Or we might get away with some clever template metaprogramming to deal with the two different types in the changed api (iterator and const_iterator). |
Looks like gcc-4.8.x has __cplusplus set to 201103L when using -std=c++11, however, erase and insert are using the C++03 api (non-const iterator). I checked gcc-4.8.2. gcc-4.9 prerelease from september 2013 has __cplusplus set to 201103L when using -std=c++11 too, and it has the C++11 api for erase and insert. So if we need to use the preprocessor we will have to additionally use some compiler version checking. |
Yeah, I did some tinkering earlier and found that |
It fails even without -std=c++11. Using clang with libc++ is enough to produce those errors.
|
@DarthGandalf What does clang++ -E give you for the containers in question? Are the definitions of erase and insert using C++11 const_iterator or pre-C++11 iterator as the input types? |
@DarthGandalf it fails because in 10.9 OSX clang uses libc++ by default instead of libstdc++
|
@wsfulton const_iterator:
@vigsterkr With libstdc++ it works, yes |
This is a minimal test replicating the problem:
The SWIG workarounds are either to change the %template to avoid use of typedef's ... there are various problems with %template and type lookups, so this is generally recommended atm anyway. So use: %template(RealVector) std::vector; Then the internals in SWIG will find std::vector::iterator and SwigValueWrapper will not be used and the code will compile. The 2nd workaround is to provide a specialization for SwigValueWrapper, such as:
Put this just before the %template. Note the 2nd operator overload to const_iterator in addition to iterator. Yuck! Any suggestions for specializing this more generally for all containers? If not, I'll put in a workaround which is simply put in a wrapper around the erase and insert methods inside an %extend. This works because the %extend wrapper uses iterator, which SwigValueWrapper will convert to, then by simply passing the parameter on to erase in the container, normal iterator to const_iterator conversion works (SwigValueWrapper does not get in the way). The ideal fix would be to not generate the SwigValueWrapper, but this is likely to require some risky changes in the type system which I am not going to tackle now. Also if users do not provide all the type information (such as the Real typedef), then SWIG won't be able to successfully look up iterator as a type and will fall back to SwigValueWrapper. On the other hand I think SwigValueWrapper should only be generated when SWIG is sure that there is no assignment operator. Currently it uses SwigValueWrapper for non-template types only if it is sure the type is non-copyable. If type information is missing, it does not use SwigValueWrapper. The behaviour for template types is different for some reason (SWIG will use SwigValueWrapper if it can't find any type information) and I don't think this is quite right. |
I'm not a TMP expert, but I think it's hard to get at function (as opposed to template) arguments. You might be able to do something with SFINAE and an rvalue reference but clang fails to fail on &&. What we can do now is to convert the const_iterator to an iterator. There's an implicit conversion back, so this should work for old and new compilers:
|
- Update to 2.0.11 - Update pkg-plist - Enable STAGE support - Backport C++11 SWIG fixes from upstream for games/py-fife [1][2] - Use GNU Make as recommended by upstream [3] - Modernise LIB_DEPENDS - Add regression-test: target to make running the test suite easier - pkg-descr: Tab to space in WWW: [1] Commit: swig/swig@92128ee [2] Issue: swig/swig#73 [3] http://www.swig.org/Doc2.0/Preface.html PR: ports/185684 Submitted by: koobs Approved by: Jason Bacon <jwbacon@tds.net> (maintainer) MFH: 2014Q1
Is there a reason why this fix was not added to swig 2.0 as well? The freebsd-ports backport works quite well for me. |
A backport to the 2.0 branch would be handy, its highly desirable to only keep local patches temporarily in the ports tree |
There are no plans for another 2.0 release. The next release of SWIG is 3.0.0 and the fix is in master ready for this release. The primary focus for 3.0.0 is c++11 and nested structs so you should probably be upgrading to 3.0.0 when it comes out if you want c++11 support. Is there a problem upgrading to 3.0.0? |
Well, apart from the fact that there is no stable version available, there is none. Master seems to run just fine on my mac (apart from building the documentation, which is due to a bug in yodl on OS X). I just thought it would be nice if this feature was backported. Assuming that you use semantic versioning, a step from 2.0.0 to 3.0.0 sounds like a lot of stuff might break and that there are some backward compatibility issues. Since I consider c++11 support an important feature, I seems to be weird to force user to upgrade to 3.0.0 and make them rewrite their code instead of just merging three little patches. |
Agreed that it would be nice to backport it. If there were more developers we could probably find the time for more releases, but help is in short supply. There is quite a reasonably big effort required in making a new release. I could do one, if there was some sponsorship available or more help about in getting version 3 ready. I do this all in my spare time. Very little should break in version 3. It has been developed with the same high degree of backwards compatibility in mind as other minor releases, with some possible tweaks for nested classes being needed and support for .NET 1.1 was dropped. You could help by trying it out and reporting/fix any issues. It should be released within a few weeks. |
I can help by creating a devel/swig30 FreeBSD port utilising the github repository sources in lieu of a future release. If someone could help facilitate by creating the appropriate tags for me to fetch against, that would be fantastic. A unmoving named target is preferable to a commit hash. This will at least get the current sources into the hands of FreeBSD developers, port maintainers and users in a convenient-to-play-with form, and at most will identify issues that can be sorted out prior to release. A tag like an 3.0.0-rc1 (or beta1 if its not yet RC-ready) should be representative enough to work with |
@koobs, we need to make one more change in the nested class area then it will be ready for a beta release. It will probably be done this weekend as mentioned on the swig-devel mailing list. I will create a label for you to use when done. |
…ers. The erase and insert methods in the containers use const_iterator instead of iterator in C++11. There are times when the methods wrapped must match the parameters exactly. Specifically when full type information for template types is missing or SWIG fails to look up the type correctly, for example: %include <std_vector.i> typedef float Real; %template(RealVector) std::vector<Real>; SWIG does not find std::vector<Real>::iterator because %template using typedefs does not always work and so SWIG doesn't know if the type is copyable and so uses SwigValueWrapper<iterator> which does not support conversion to another type (const_iterator). This resulted in compilation errors when using the C++11 version of the containers. Closes #73 Conflicts: CHANGES.current Lib/std/std_unordered_map.i Lib/std/std_unordered_set.i
There was quite a lot of interest in a 2.0.12 release, so I've spent the weekend creating, testing and releasing it. It should contain the fixes you need. I'll do a tag in a day or two for 3.0.0 |
Much appreciated William :) |
I've created a rel-3.0.0-beta1 tag. There aren't going to be any major changes until the release apart from some Lua changes. Any feedback from FreeBSD testing will be appreciated. |
- Update to 2.0.12 - Remove C++11 support patches (upstreamed [1]) Changes: https://github.com/swig/swig/blob/rel-2.0.12/CHANGES.current [1] swig/swig#73 PR: 186817 Approved by: maintainer
- Update to 2.0.12 - Remove C++11 support patches (upstreamed [1]) Changes: https://github.com/swig/swig/blob/rel-2.0.12/CHANGES.current [1] swig/swig#73 PR: 186817 Approved by: maintainer git-svn-id: svn+ssh://svn.freebsd.org/ports/head@361017 35697150-7ecd-e111-bb59-0022644237b5
- Update to 2.0.11 - Update pkg-plist - Enable STAGE support - Backport C++11 SWIG fixes from upstream for games/py-fife [1][2] - Use GNU Make as recommended by upstream [3] - Modernise LIB_DEPENDS - Add regression-test: target to make running the test suite easier - pkg-descr: Tab to space in WWW: [1] Commit: swig/swig@92128ee [2] Issue: swig/swig#73 [3] http://www.swig.org/Doc2.0/Preface.html PR: ports/185684 Submitted by: koobs Approved by: Jason Bacon <jwbacon@tds.net> (maintainer) MFH: 2014Q1
- Update to 2.0.12 - Remove C++11 support patches (upstreamed [1]) Changes: https://github.com/swig/swig/blob/rel-2.0.12/CHANGES.current [1] swig/swig#73 PR: 186817 Approved by: maintainer
When trying to use c++11 mode with clang, i.e. the -std=c++11 -stdlib=libc++ flags are set, the swig generated cxx cannot be compiled.
An example of the error:
The text was updated successfully, but these errors were encountered: