New user self-registration is disabled due to spam. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Before reporting a bug, please make sure that your Eigen version is up-to-date!
Bug 829 - No need for specialized std::vector in C++11
Summary: No need for specialized std::vector in C++11
Status: RESOLVED FIXED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - vectorization (show other bugs)
Version: 3.3 (current stable)
Hardware: All All
: Normal Compilation Problem
Assignee: Nobody
URL:
Whiteboard:
Keywords:
: 919 (view as bug list)
Depends on:
Blocks: 3.3
  Show dependency treegraph
 
Reported: 2014-06-24 10:24 UTC by Michael Becker
Modified: 2015-08-16 18:41 UTC (History)
5 users (show)



Attachments

Description Michael Becker 2014-06-24 10:24:10 UTC
In C++11 the interface of std::vector was changed and functions like resize() are now taking their value_type parameters as reference. This should fix the alignment problem of std::vector entirely and the need for a specialized version unnecessary. So the only thing you have to do in C++11 is use aligned_allocator.

But if you include Eigen/StdVector you introduce a partial template specialization of std::vector into your code which replaces the standard implementation as soon as you use aligned_allocator. This silently gives you a C++98 implementation of std::vector and very hard to find errors when using C++11 features (e.g. initializer lists).

Code to reproduce the error:

#include <vector>
#include <Eigen/Eigen>
#include <Eigen/StdVector> // <- remove this include to make it work

int main()
{
    std::vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> points = { {0,0}, {0,1} };
}

So my suggestion to fix this would be to omit specialization of std::vector in case of C++11.
Comment 1 Christoph Hertzberg 2014-07-15 18:56:27 UTC
In principle the fix is easy: #if-guard the specialization of the std-containers.
But we need a portable way to detect if the implementation is correct already.
For gcc checking
  #if __cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X__)
should be sufficient. What about MSVC and clang?
Comment 2 Christoph Hertzberg 2014-12-16 12:45:06 UTC
*** Bug 919 has been marked as a duplicate of this bug. ***
Comment 3 Michael Hofmann 2014-12-16 13:58:25 UTC
For MSVC, something like
  #if defined(_MSC_VER) && (_MSC_VER >= 1900)
should do the trick. _MSC_VER==1900 for VC++ 2015 Preview; which is the first version where certain things break due to the use of the StdVector header (see Bug 919).
The value of __cplusplus still returns 199711L for any current version of Visual Studio, so it cannot be relied on.

The above #define from comment #1 should also work for Clang, since Clang returns a proper value for the __cplusplus definition.
Comment 4 Christoph Hertzberg 2014-12-16 15:46:29 UTC
Can you check if the following works with VC2015 (with assertions enabled):

  #include <vector>
  #include <Eigen/Core>

  int main() {
    std::vector<Eigen::Matrix4f, Eigen::aligned_allocator<Eigen::Matrix4f> > test;
    test.resize(2);
    test.resize(4, Eigen::Matrix4f::Identity());
  }

If possible, can you also look up the declaration of std::vector::resize in your version? It should get its default value type by const reference (not by value), cf:
http://www.cplusplus.com/reference/vector/vector/resize/

There seems to be still the C++98 definition for MSVC2013, according to:
http://msdn.microsoft.com/en-us/library/wezs0zy6(v=vs.120).aspx
Comment 5 alexis.ts 2015-08-12 09:07:31 UTC
The above code runs on VS2015 without a problem (tested in release/debug mode on 32 and 64 bit).

The std::vector::resize declaration looks like this:
void resize(size_type _Newsize, const value_type& _Val)
Comment 6 Christoph Hertzberg 2015-08-14 14:19:22 UTC
Thanks for looking into this. I introduced a EIGEN_HAS_CXX11_CONTAINERS macro:
https://bitbucket.org/eigen/eigen/commits/2e01c760769be

We should also warn from using the EIGEN_DEFINE_STL_{VECTOR,DEQUE,LIST}_SPECIALIZATION macros (which should have said STD instead of STD, btw ...), since these don't propagate the C++11 constructors. Is deprecating a macro possible somehow?

I only committed this to the devel branch, since C++11 support of the stable branch is incomplete anyways (and it is easy to workaround this, by not including the corresponding Eigen headers in C++11 mode)
Comment 7 Gael Guennebaud 2015-08-16 12:29:21 UTC
What about defining the EIGEN_DEFINE_STL_* macros to nothing in C++11 mode?
Comment 8 Christoph Hertzberg 2015-08-16 18:41:21 UTC
These macros also specialize a container to use the aligned allocator by default:
http://eigen.tuxfamily.org/dox-devel/group__TopicStlContainers.html#vector_spec

A 'problem' is that most systems are 64bit now and the issue hardly occurs anymore (however, with AVX/32byte alignment it is likely to happen more frequently again).

Shall we re-open this as documentation issue?

Note You need to log in before you can comment on or make changes to this bug.