简体   繁体   中英

VC++ 11 - std::condition_variable_any not compatible with standard?

Recently, I ran into strange compilation issues on Microsoft Visual Studio 2012 (equipped with Visual C++ 11).

I ported large code base, developed mostly on Linux with extensive C++ 11 usage in mind. Despite few minor changes, everything was working fine. Except one thing: I got strange error about result type of std::condition_variable::wait_for . Its content is irrelevant here, because I checked this and...

Reference page (linked above) says:

template< class Lock, class Rep, class Period >
std::cv_status wait_for(Lock&, const std::chrono::duration<Rep, Period>&)

And:

template< class Lock, class Rep, class Period, class Predicate >
bool wait_for(Lock&, const std::chrono::duration<Rep, Period>&, Predicate)

I have used std::cv_status in some places, so I can say, I rely on its presence. However, on MSVC11 , <conditional_variable> contains:

template<class _Lock, class _Rep, class _Period>
bool wait_for(_Lock& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time)

And:

template<class _Lock, class _Rep, class _Period, class _Predicate>
bool wait_for(_Lock& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time, _Predicate _Pred)

Note the different result type in first case. I was like:

Errr... what?

I checked this immediately back on Linux ( g++ 4.8 ) and these two methods were indeed defined properly.

What's going on here? MS has released implementation not compatible with standard?

Curious thing is, that I further investigated <condition_variable> and I have found this:

namespace cv_status {   // names for wait returns
    enum cv_status {
        timeout,
        no_timeout
    };
} // namespace cv_status

But it is:

  • unused
  • invalid (*)

Is this some well-known bug? Or perhaps standard allows implementations to do this?


(*) Standard defines enum class cv_status , not enum class cv_status::cv_status .


One more thing: wait_for calls internally wait_until , which looks like this:

bool _Res;
_Mtx_lock(&_Mtx);
_Xtrnl.unlock();
_Res = _Cnd_timedwaitX(&_Cnd, &_Mtx, _Abs_time) != _Thrd_timedout;
_Mtx_unlock(&_Mtx);
_Xtrnl.lock();
return (_Res);

So, interpretation of the result is:

  • true -> std::cv_status::no_timeout
  • false -> std::cv_status::timeout

If there was requirement, that no_timeout must be defined as 1 and timeout as 0 it would be fine, but I don't see anything like this. Actually, on Linux, there was:

enum class cv_status { no_timeout, timeout };

So these enumerators would be converted to bool in different way than on Windows.

Despite the version number of Visual C++ 11.0, Visual Studio 2012 does not support C++11 and does not claim to support it. Not even the next version (Visual Studio 2013) does: there is a CTP to add significant C++11 features, but even then, the support is incomplete. Visual Studio 2015 is expected to be mostly C++11 feature-complete, language-wise, but I'm not sure if the standard library implementation will be as well.

While C++11 was being standardised, there was a point where this function was specified to return bool . It was at this point that Microsoft added it to their implementation, and as C++11 was not supported anyway, it was simply not updated when the standard got updated.

The comments point out that this particular function was changed in VS2013 already, but still, if you want a C++11 implementation, then neither VS2012 nor VS2013 will do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM