attempting to reference a deleted function for atomic c++ - c++

I have a piece of code that use to work for Visual Studio 2013. Now that I'm trying to build the same code in Visual Studio 2017 it complains. Here is the code I'm trying to do.
#include <array>
#include <atomic>
int main()
{
using TrdRobotStateArray = std::array<std::atomic<double>, 6>;
TrdRobotStateArray mCurrentPose = { 0.3 };
printf("%0.3f", mCurrentPose[0]);
return 0;
}
With this, I get this error:
error C2280: 'std::atomic<double>::atomic(const std::atomic<double> &)': attempting to reference a deleted function
I didn't write this code, and I'm trying to read into atomic variables. But I'm still not quite sure what is going on with the error. An explanation about atomics would be greatly appreciated. Thanks!
update:
Here are all the errors and warnings that came with this code. So it would help others in the future.
1>AtomicTest.cpp
1>AtomicTest.cpp(13): error C4839: non-standard use of class
'std::atomic<double>' as an argument to a variadic function
1>AtomicTest.cpp(13): note: the constructor and destructor will not be
called; a bitwise copy of the class will be passed as the argument
1>AtomicTest.cpp(11): note: see declaration of 'std::atomic<double>'
1>AtomicTest.cpp(13): error C2280: 'std::atomic<double>::atomic(const
std::atomic<double> &)': attempting to reference a deleted function
1>C:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\include\atomic(689):
note: see declaration of 'std::atomic<double>::atomic'
1>C:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\VC\Tools\MSVC\14.11.25503\include\atomic(689):
note: 'std::atomic<double>::atomic(const std::atomic<double> &)': function
was explicitly deleted
1>AtomicTest.cpp(13): warning C4477: 'printf' : format string '%0.3f'
requires an argument of type 'double', but variadic argument 1 has type
'std::atomic<double>'
1>Done building project "AtomicTest.vcxproj" -- FAILED.

You have to load the value explicitely in order to compile it:
printf("%0.3d", mCurrentPose[0].load());
Otherwise, it will try to copy the atomic variable itself for printf() which clearly is not the intent.

Atomic variables are not CopyConstructible.
This is a requirement of the C++ standard, so VisualStudio 2017 is correct.

Related

C2143/C2518 when trying to compile project using boost.multiprecision

I've been having problems trying to get boost.multiprecision to work in my VC2017 project, and I tried to make the simplest project possible as a proof of concept:
#include<boost/multiprecision/cpp_int.hpp>
int main() {
boost::multiprecision::cpp_int val{ 5 };
val *= 5;
val *= 5;
return val.convert_to<int>();
}
Unfortunately, this code does not compile, with the following errors:
1>------ Build started: Project: Multiprecision Test, Configuration: Debug x64 ------
1>Multi Main.cpp
1>Unknown compiler version - please run the configure tests and report the results
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(36): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(40): note: see reference to class template instantiation 'boost::equal_pointees_t<OptionalPointee>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(59): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\utility\compare_pointees.hpp(63): note: see reference to class template instantiation 'boost::less_pointees_t<OptionalPointee>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(453): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(467): note: see reference to class template instantiation 'boost::numeric::convdetail::trivial_converter_impl<Traits>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(453): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(454): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(474): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(497): note: see reference to class template instantiation 'boost::numeric::convdetail::rounding_converter<Traits,RangeChecker,RawConverter,Float2IntRounder>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(474): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(475): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(504): error C2143: syntax error: missing ',' before '<'
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(526): note: see reference to class template instantiation 'boost::numeric::convdetail::non_rounding_converter<Traits,RangeChecker,RawConverter>' being compiled
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(504): error C2518: keyword 'typename' illegal in base class list; ignored
1>g:\workspacec\solutions\project4x\library\include\boost\numeric\conversion\detail\converter.hpp(505): error C2518: keyword 'typename' illegal in base class list; ignored
1>Done building project "Multiprecision Test.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 2 up-to-date, 0 skipped ==========
These are the exact same errors I'm getting in the more complex project that originally used boost.multiprecision. I had no problems getting this code to compile in Visual Studio 2015. Does anyone know what's wrong, and what I need to do to fix it?
EDIT:
A project using boost.asio compiles with no issues:
#include<boost/asio.hpp>
#include<iostream>
int main() {
boost::asio::io_service service;
for (int i = 0; i < 10; i++) {
service.post([i] {
std::cout << i << std::endl;
});
}
service.run();
system("pause");
return 0;
}
The problem is caused by the fact that some templates in boost::multiprecision use std::unary_function, which has been deprecated since C++11 and was removed from the standard for C++17.
The standard library implementation in MSVC 2015 introduced guards like #if _HAS_AUTO_PTR_ETC around such deprecated definitions. They are set to 1 by default under the new switch /std:c++14 (the default) and set to 0 by default under /std:c++latest (the new compiler switches are available since 2015 Update 3).
So, until boost removes the dependencies on std::unary_function, you have to either not use /std:c++latest (I've always been using it since it came out) or #define _HAS_AUTO_PTR_ETC 1 before including (directly or indirectly) any standard library headers. So, either set it with compiler options or in some PCH that is the first that gets included in all translation units or something like that.
A thorough description of these settings, including other guards that control other deprecated or removed features, can be found in this blog post by Stephan T. Lavavej. The Visual C++ change history 2003 - 2015 seems to be the official list of breaking changes in MSVC, but unfortunately it doesn't cover all these details. In general, scanning the Visual C++ Team Blog for posts from Stephan will give you the best info on these things.

C++, curious compiler error when implementing a function `int next(std::string param)`

I've been badly bitten by the following code, on which I wasted many hours of precious time.
#include<string>
int next(std::string param){
return 0;
}
void foo(){
next(std::string{ "abc" });
}
This produces the following compiler error (on Visual Studio 2013):
1>------ Build started: Project: sandbox, Configuration: Debug Win32 ------
1> test.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2039: 'iterator_category' : is not a member of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
1> c:\users\ray\dropbox\programming\c++\sandbox\test.cpp(8) : see reference to class template instantiation 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>' being compiled
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2146: syntax error : missing ';' before identifier 'iterator_category'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2602: 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category' is not a member of a base class of 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371) : see declaration of 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category'
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility(371): error C2868: 'std::iterator_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char>>>::iterator_category' : illegal syntax for using-declaration; expected qualified-name
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I found out later that if I change my function name from next() to something else, all is fine. To me, this indicates that there is a name conflict, specifically of the name next. I find this strange because I didn't use anything like using namespace std. As far as I know, next is not a built-in C++ keyword (is it?). I looked up next here, but it's std::next and as I said I didn't using namespace std. So how did this conflict happen? How do I prevent similar things in the future? What other names might cause a conflict like this?
There are several things going on here, interacting in subtle ways.
Firstly, an unqualified call to next with an argument of type std::string means that as well as your own next function, the standard function template std::next is found by Argument-dependent lookup (ADL).
After name lookup has found your ::next and the standard library's std::next it performs overload resolution to see which one is a better match for the arguments you called it with.
The definition of std::next looks like:
template <class ForwardIterator>
ForwardIterator next(ForwardIterator x,
typename std::iterator_traits<ForwardIterator>::difference_type n = 1);
This means that when the compiler performs overload resolution it substitutes the type std::string into std::iterator_traits<std::string>.
Prior to C++14 iterator_traits is not SFINAE-friendly which means that it is invalid to instantiate it with a type that is not an iterator. std::string is not an iterator, so it's invalid. The SFINAE rule does not apply here, because the error is not in the immediate context, and so using iterator_traits<T>::difference_type for any non-iterator T will produce a hard error, not a substitution failure.
Your code should work correctly in C++14, or using a different standard library implementation that already provides a SFINAE-friendly iterator_traits, such as GCC's library. I believe Microsoft will also provide a SFINAE-friendly iterator_traits for the next major release of Visual Studio.
To make your code work now you can qualify the call to next so ADL is not performed:
::next(std::string{ "abc" });
This says to call the next in the global namespace, rather than any other next that might be found by unqualified name lookup.
(Updated per Jonathan's comments)
There are two views here, the C++11 and the C++14 view. Back in 2013, C++11's std::next was not properly defined. It is supposed to apply to iterators, but due to what looks like an oversight it will cause hard failures when you pass it a non-iterator. I believe the intention was that SFINAE should have prevented this; std::iterator_traits<X> should cause substitution failures.
In C++14, this problem is solved. The definition of std::next hasn't changed, but it's second argument (std::iterator_traits<>) is now properly empty for non-iterators. This eliminates std::next from the overload set for non-iterators.
The relevant declaration (taken from VS2013) is
template<class _FwdIt> inline
_FwdIt next(_FwdIt _First,
typename iterator_traits<_FwdIt>::difference_type _Off = 1)
This function should be added to the overload set if it can be instantiated for the given arguments.
The function is found via Argument Dependent Lookup and Microsoft's header structure. They put std::next in <xutility> which is shared between <string> and <iterator>
Note: _FwdIt and _Off are part of the implementation namespace. Don't use leading underscores yourself.
Actually std::next() is a function defined in <iterator> which returns the next iterator passed to std::next(). Your code is running on my computer with gcc-4.9.2. More : http://en.cppreference.com/w/cpp/iterator/next
The code I used:
#include<string>
#include <iostream>
int next(std::string param){
std::cout<<param<<std::endl;
return 0;
}
void foo(){
next(std::string{ "abc" });
}
int main()
{
foo();
return 0;
}
Also on ideone : http://ideone.com/QVxbO4
The compiler found standard function std::next due to the so-called Argument Dependent Lookup because the argument used in the call - std::string - is declared in namespace std.

C++ Directly calling a vector element's function (Eclipse CDT bug?)

I'm getting a weird error when trying to call a vector element's function. For example, if I do this
However it works fine if I do this:
The code runs fine in Visual Studio, so is this a bug with Eclipse CDT?
P.S. ignore the endl bug
EDIT:
Compiler error from Visual C++
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\Include\vector(1494) : error C2528: '_Ptr' : pointer to reference is illegal
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\Include\vector(1658) : error C2528: '_Pval' : pointer to reference is illegal
Compiler error from MinGW
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_vector.h:87:68: error: using invalid field 'std::_Vector_base<_Tp, _Alloc>::_Vector_impl::_M_finish'
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_vector.h:87:68: error: using invalid field 'std::_Vector_base<_Tp, _Alloc>::_Vector_impl::_M_end_of_storage'
Note that it compiles fine in Visual Studio
EDIT 2:
ok so...now it works for some reason. Yes I was wrong for choosing the back() method as an example, because it was failing for any method I tried. But for some reason, after a couple days of this problem, Eclipse fixed itself, and now the only error message I get from this code is
..\src\main.cpp:48:21: error: 'class std::basic_string<char>' has no member named 'back'
I wouldn't be surprised if the issue came back though, but I guess it really is a problem with Eclipse, either with the IDE itself or with my environment/linker settings
It appears that std::basic_string::back is new in C++11. So unless you compile in C++11 mode (using -std=c++11 for gcc, for example), it's not going to compile. Here's the complete test code I used:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> strings;
strings.push_back("test");
std::cout << strings[0].back() << '\n';
}
So, you'd have to configure your Eclipse to use C++11 mode, also.

std::forward compiling error VS2010

I am getting a weird error that I can't understand(since it's from a native file of VS) from file utility(it's located in C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\), it is being compiled in my project with Visual C++ 10.0.
'std::forward' : cannot convert parameter 1 from '' to '&'
template<class _Other1, class _Other2>
pair(_Other1&& _Val1, _Other2&& _Val2)
: _Mybase(_STD forward<_Other1>(_Val1), _STD forward<_Other2>(_Val2))
{ // construct from moved values
}
Can anyone explain this error? It seems to me very strange, but I'm totally new to C++ and I don't understand how to fix it.
The error seems to be here:
std::map<std::string, DWORD>::value_type("SOME_STRING", 8192);
And the compilation reports this:
see reference to function template instantiation
'std::pair<_Ty1,_Ty2>::pair<const char(&)[12],>(_Other1,_Other2 &&)'
being compiled with
[
_Ty1=const std::string,
_Ty2=DWORD,
_Other1=const char (&)[12],
_Other2=
]
It seems the compiler is incapable of coping with the string literal passed in. I don't know whether it's a bug in the standard library implementation VS2010 uses, or whether it hits an edge case in the standard (and is actually supposed to fail), but either way, you can solve it by explicitly creating a std::string from the literal:
std::map<std::string, DWORD>::value_type(std::string("SOME_STRING"), 8192);

How can I test the portability of a C++ codebase developed and managed in Visual Studio 2010?

I have a very large and very old C++ project currently maintained in Visual Studio 2010. One member of our team has just tested the bumpiness of the upgrade path to VS 2012, and found we were being affected by this, through our use of Microsoft's non-standard extensions to the language.
Is there any tool we can run over our codebase that will tell us how many other non-standard extensions we're using, so we can eliminate them before they cause us any more problems?
Specify the compiler switch /Za which disables extensions.
For example, the following code:
#include <string>
void f(std::string&) {}
int main()
{
f(std::string("hello"));
}
Compiles (with warning) when /Za is not specified but fails to compile when /Za is specified with the following error:
main.cpp(7) : error C2664: 'f' : cannot convert parameter 1 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'std::string &'
with
[
_Elem=char,
_Traits=std::char_traits,
_Ax=std::allocator
]
A non-const reference may only be bound to an lvalue