I was surprised to find in Visual Studio 2012 Update 1 the following does not compile anymore:
[](unique_ptr<int>){};
Compiler error states it can't access the private copy constructor of unique_ptr.
The above worked just fine in Visual Studio 2010.
It also compiles just fine in gcc 4.7.2
Is this a known bug, or is this actually expected behavior? I could not find anything on Microsoft Connect.
EDIT: I have just updated to Visual Studio 2012 Update 2, the issue still occurs.
EDIT2: I have filed a bug report on Microsoft Connect, you are welcome to upvote it if it affects you too.
Try this:
int a;
[a](unique_ptr<int>){};
It doesn't matter what it is, just capture something explicitly.
I am still not sure whether this is a bug, it certainly looks like it.
In the meantime, a logical equivalent of
[](unique_ptr<int> aArg)
{
};
can be written as
[](unique_ptr<int> && aArg)
{
unique_ptr<int> arg = std::move(aArg);
};
It's not a very nice approach for me as I am writing library code. The lambda's caller is the library and the lambda is user provided. I do not wish to impose on users that they manually std::move the argument.
So, while this is not practical for me, it might come in handy to someone else.
Related
I'm updating a huge legacy system, and am currently stumped by the following function:
template <class EL>
EL& FastInsertVector<EL>::operator[](size_type index)
{
return (EL&) FastInsertVectorBase::operator [][](index);
}
MS VC++ 2022 compiles it happily, whereas C++ Builder 11.1.5 rejects it saying:
expected expression
If I remove the second set of [], both compilers are happy. Unfortunately, this is shared code that both compilers must be able to handle.
This codebase is huge, and has no tests, and I'm having difficulty actually understanding what this syntax even means.
Is this valid C++ syntax? Can anyone explain what it's trying to express?
I have the following code on c++17
template<typename T>
std::vector<T*> getPointerVector(std::vector<T> base) {
auto out = std::vector<T*>();
for (auto& t : base) {
out.push_back(&t);
}
return out;
}
As far as i understand RVO should kick in and prevent any copying of the returned vector. However, when i use GCC it all works fine, using msvc it does not and the vector is actually copied. Any explanations? Thanks!
Edit:
When I debugged I made sure the reference in memory is the same for the vector inside the function and on the calling side. That is true for gcc 8.3 on debian testing and not true for msvc on visual studio 19.4
Apparently your version of Visual Studio just doesn't do that.
Or…
When I debugged I made sure the reference in memory is the same for the vector inside the function and on the calling side. That is true for gcc 8.3 on debian testing and not true for msvc on visual studio 19.4
If you're debugging, presumably you're making a debug build, for which optimisations are usually much less fierce. So it could simply be that you turned this off.
It will at least be moving the vector, so there's that.
By the way, every element of the vector you're returning is a dangling pointer. Did you mean to take base by reference? Also, an out.reserve(base.size()) call wouldn't hurt.
I had to re-image my laptop recently, and reinstalled visual studio (Tried 2018 but it annoyed me, so i rolled back to 2015 which seems to work a lot better)
I opened up an old project, and at first it said failed to find build toolset, so i re-targeted it to the one i had just installed. And tried again to compile, and it failed telling me that in the following function:
string getinvnum(vstring range) {
int inv;
string ret;
for (int i = 0; i < range.size(); i++) {
int temp = stoi(range[i]);
if (temp > inv) {
inv = temp;
}
}
return to_string(inv);}
that cpp(266): error C4700: uninitialized local variable 'inv' used. and defiantly refuses to compile.
Line 266 is relating to the if statement there.
This is not a complex function at all, and it most surely is initialized, in fact if i hover my mouse over "inv" intellisense picks up it's deceleration.
I then decided to copy and paste my source code into a new project as this error just made no sense to me, commented out code relating to other included project files, and tried to recompile, and it worked without any complaints.
Is there something wrong with this code, or some issue with the change in toolset?
While everything is working, i'd just like to understand, if possible what happened/what i did which caused this error.
Can anyone explain to me why visual studio is doing this to me?
Edit: Just copied across the whole solution into a new project, and the entire thing now builds without any issues. However the original, while identical code, still tells me this same error.
inv is not initialised. Depending on project compiler settings, the compiler version and whether you are using debug or release the compiler may or may not detect this.
To fix the issue simply initialise inv to have an initial value. The compiler is trying to protect you against difficult to find bugs due to inv having some random value (which may work sometimes as that random value may be 0).
Yes it's an error - a logical error at least - as others have pointed out. You should not ignore compiler warnings, you should fix them. MSVC will always warn you about this (and other things) unless you explicitly turn warnings off so be on the lookout in future and pay due attention. Whether you should tell the compiler to treat warnings as errors is another matter. I don't. Opinions vary.
But I have a more specific reason for posting this answer. In DEBUG builds, The Visual Studio debugger will alert you (with a popup) at runtime if you use an uninitialised variable and show you exactly where you did so. So, always run your code under the debugger and then you will be alerted to mistakes like this, even if you miss the compiler warning.
I am trying to test a little C++17. I am trying to do:
[[nodiscard]] int get_value1()
{
return 42;
}
inline void start()
{
// Should generate warning
get_value1();
}
However, it does not. I am using Visual studio 2017. Warning level set to Level4(\W4). I have set C++ Language Standard to ISO C++ Latest Draft Standard (/std:c++latest).
But it does not generate the warning that I want. Why is that? Also, a little side question: That tab to select the language standard only appears in Debug configuration and not Release. Why is that? Release complains on the nodiscard, Would that mean that Release is in C++14?
edit: naturally I meant warning in the second section. Corrected. :)
Actually [[nodiscard]] is supported only since VS 2017.3 and it should give you a warning, not an error. And as I understand specification assumes that compiler may warn you. And may not.
I recently installed the Visual Studio 11 Developer Preview. While playing with threads and futures, I came around this setup:
#include <future>
#include <iostream>
int foo(unsigned a, unsigned b)
{
return 5;
}
int main()
{
std::future<int> f = std::async(foo, 5, 7);
std::cout << f.get();
}
So, very simple. But since there are two arguments for "foo", VS 11 doesn't want to compile it. (However, g++ does: http://ideone.com/ANrPj) (The runtime error is no problem: std::future exception on gcc experimental implementation of C++0x) (VS 11 errormessage: http://pastebin.com/F9Xunh2s)
I'm a little confused right now, since this error seems extremely obvious to me, even if it is a developer preview. So my questions are:
Is this code correct according to the C++11 standard?
Is this bug already known/reported?
std::future is supposed to be a variadic template. This is what allows you to pass an arbitrary number of arguments to the function being invoked asynchronously.
Unfortunately, the current preview of VS 11 doesn't support variadic templates, which means it doesn't have the mechanism for you to pass more than one argument to the function.
Bottom line: VS is wrong. I'm not sure if anybody has reported this as a bug, but it's a direct consequence of a fact that's already well known, so reporting it probably wouldn't/won't do a whole lot of good other than indirectly adding a vote that variadic templates are important.
If you look on the VC++ News page, they (currently) have a link to a survey that's supposed to allow you to indicate priorities you'd assign to conformance with various C++11 features. Unfortunately it seems to be offline, at least at the moment. When you can, filling it in to indicate that you consider variadic templates a high priority has at least some chance of doing some good for this (though I obviously can't guarantee anything).
Try below adhoc workaround. (I tried at Visual Studio 11 Beta)
std::future<int> f = std::async(std::launch::any, foo, 5, 7);
As C++11 standards function std::async() has two overloads, but MSVC/CRT can't do correct overload resolution. Furthermore std::launch::any is NOT a part of standard. (it requires std::launch::async|std::launch::deferred, but they can't compile again)