I encountered a compiler crash and intellisense false positives with Visual Studio 2015 using C++.
This crashes the compiler when written within a function block:
if();
This is the dialog that is shown when compiling (I am on a German version of Windows):
Even though the compiler crashes, I get error list output:
Error C2059 syntax error: ')'
Warning C4390 ';': empty controlled
statement found; is this the intent?
Error C1903 unable to recover from previous error(s); stopping compilation
This produces squiggles and error annotations in the vertical scrollbar in map mode, but no actual intellisense errors:
#include <vector>
struct S { std::vector<S> Children; };
int main(int argc, char* argv[]) {
S item;
item.Children.push_back(S());
// ^
// Error: no instance of overloaded function
// "std::vector<_Ty, _Alloc>::push_back [with _Ty=S, _Alloc=std::allocator<S>]"
// matches the argument list
// argument types are: (S)
// object type is: std::vector<S, std::allocator<S>>
S& back = item.Children.back();
// ^^^^
// Error: a reference of type "S &" (not const-qualified) cannot be
// initialized with a value of type "S"
return 0;
}
Are those bugs? Are they known? Can you reproduce them?
For the first case: the compiler shouldn't crash but just issue the diagnostic you show. So yes, that's a bug. Which doesn't occur in VS2013 btw. Submit a report for it here
For the second case: it is the same in VS2013 and is due to nesting a vector of S inside S. This and other cases make the error squiggles appear incorrectly, it is actually not that uncommon. But ideally it should not happen so you can submit a bug report for it as well, though it might be something which is going to be labelled 'wontfix' as the compiler team usually focusses on more urgent cases.
Related
Having such a super simple char array definition:
const int g_msgbuf_size = 200;
char g_msgbuf[g_msgbuf_size];
giving me an totally unreasonable error:
error C2057: expected constant expression
on the second line while compiling in MSVC 2019.
When i try the code on any other c++ compiler like https://www.onlinegdb.com/online_c++_compiler or http://cpp.sh/ everything goes well - I get no errors as expected.
Why does the MSVC 2019 makes me problems?
When i include uhd/usb_control.hpp in my main.cpp :
#include <uhd/transport/usb_control.hpp>
/* Some other includes */
int main (void)
{
uhd::transport::usb_control::sptr usbSpeed;
usbSpeed = uhd::transport::usb_control::make(handle, 0);
/* `handle` is a `usb_device_handle::vid_pid_pair_t` */
}
I got error from here:
static sptr make(usb_device_handle::sptr handle, const int interface);
Error:
unexpected token struct. Did you forget a ';'
struct: missing tag name
And another strange error in:
usbSpeed = uhd::transport::usb_control::make(handle, 0);
Error:
Cannot convert argument 2 from int to const int
The only implementation that i find for uhd::transport::usb_control::make is uhd/transport/usb_dummy_impl.cpp which only throw an exception.
Environment information:
Compiler: MS Visual Studio 2017
OS: MS Windows 10
C++ Standard: 17
How to fix those errors ? I only what to detect the USRP usb type. For this i read the uhd source code and i find the uhd/transport/usb_control.hpp, But I have encountered those errors.
maybe the cause of this unexpected behavior is related to your included files and a conflict between some of them, as you mentioned in addition of #include <uhd/transport/usb_control.hpp> you have some other includes. i suggest move this include line upper and lower of other includes and test your code again.
wish my suggest be useful.
EDIT: added the compiler errors at the end.
First I'll say I have both Visual Studio Express 2013 and CodeBlocks (Mingw w64) set up and running.
But I am having a problem with some code compiling with one compiler but not the other and vis-versa.
Consider this code:
void foo(std::string& s){
std::cout << "in foo function now" << std::endl;
s = "the new string.";
}
int main(){
std::string s = "the original string";
std::thread t1(foo, std::ref(s));
t1.join();
if (!s.size()) std::cout << "s is empty" << std::endl;
else std::cout << s << std::endl;
std::cin.get();
return 0;
}
It compiles and runs fine on both GCC and VS.
BUT if I decide to change std::ref(s) with std::move(s) it won't compile with GCC anymore but it will with VS.
To fix it I have to add a '&' so void foo(std::string& s) becomes void foo(std::string&& s), THEN it will compile with gcc but it won't with VS anymore!
My guess would be that the VS compiler is quiet forgiving and is not following the standard to the letter but I haven't withness such a behavior with std::function and std::bind even though the arguments are passed the same way I believe.
At any rate I would very much appreciate some help in understanding what is going on.
EDIT: The errors:
The GCC one:
C:/mingw-w64/x86_64-5.1.0-posix-seh-rt_v4-rev0/mingw64/x86_64-w64-mingw32/include/c++/functional:1505:61: error: no type named 'type' in 'class std::result_of<void (*(std::__cxx11::basic_string<char>))(std::__cxx11::basic_string<char>&)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
C:/mingw-w64/x86_64-5.1.0-posix-seh-rt_v4-rev0/mingw64/x86_64-w64-mingw32/include/c++/functional:1526:9: error: no type named 'type' in 'class std::result_of<void (*(std::__cxx11::basic_string<char>))(std::__cxx11::basic_string<char>&)>'
_M_invoke(_Index_tuple<_Indices...>)
The VS one:
Error 1 error C2664: 'void (std::string &&)' : cannot convert argument 1 from 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' to 'std::string &&' c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional 1149 1 Tests
MSVC is wrong, both under the standard and practically.
Internally, they both copy the arguments into something tuple-like, the unpack them in the spawned thread and a call is made.
Under the standard, the invoke expression must pass the values as rvalues into the called function after copying them (well, except for std::ref cases).
This is because of the wording of the INVOKE clause in this standard. I've talked about it before here, but have not tracked it down yet.
Logically, the value in the tuple is never going to be used again, so it should be in an rvalue context not an lvalue one. Taking something by value, copying it, then passing it by reference, then throwing out the copy, is usually a bug.
I have ran into a problem compiling some template code with Visual Stuido 2010 SP1, cl.exe version 16.0.40219.1
The following code will cause the compiler to access violate:
template<typename T>
class A
{
A(){}
};
template<typename T>
class B : public A<T>
{
using A::A(); // Compiler access violates
// **EDIT**
//using A<T>::A<T>; // Compiler succeeds
//using A<T>::A(); // Compiler reports error
};
int main(int argc, char* argv[])
{
return 0;
}
It generates the following error (in addition to the "cl.exe has stopped working, C0000005 exception):
1>d:\projects\cpptest\cpptest\cpptest.cpp(11): fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'msc1.cpp', line 1420)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
The code compiles fine (well, that is, it emits a proper error message and doesn't crash the compiler) in Dev-C++ with g++.
main.cpp:11: error: `template<class T> class A' used without template parameters
main.cpp:11: error: expected nested-name-specifier before "A"
main.cpp:11: error: using-declaration for non-member at class scope
main.cpp:11: error: expected `;' before '(' token
main.cpp:11: error: expected unqualified-id before ')' token
make.exe: *** [main.o] Error 1
EDIT
The following, however, compiles fine, without access violation, so it seems this is related to templates:
class A
{
A(){}
};
class B : public A
{
using A::A;
};
int main(int argc, char* argv[])
{
return 0;
}
Do you think this is worth reporting to Microsoft? Can anyone else reproduce this?
Maybe try in Visual Studio 2013 to see if it still occurs?
Since this is reproducible by others on Visual C++ platforms, I have opened a bug report on Microsoft Connect as "answer".
Also, as workaround, the following syntax works:
using A<T>::A<T>;
Update 2013-12-06: Microsoft has confirmed the issue and the issue will be fixed in the Visual Studio 2013 C++ compiler.
I am trying to take a list data type I created and make it a template. In doing so I've run into the following obscure problem. I can post all of the code if needed, but this is really the function that is causing the problem.
Note: This code was compiling just fine until I got to this method. I was compiling after writing every few lines as a sanity check, and everything was fine, but then I get to this point and it blows up. If I take the try/catch block out of this method it compiles just fine, so I'm pretty sure the problem is isolated there, not a missing semicolon in a header/etc. as reported from other answers -- though I did of course triple-check to be sure! :)
Here's the code that is causing the problem:
template<class T>
bool UnsortedListType<T>::IsFull()
{
try { return false; }
catch(std::bad_alloc exception) { return true; } // line 35
}
Like I said, I simplified it as much as possible while still triggering the error. Here is the error:
UnsortedListType.cpp||In member function 'bool UnsortedListType<T>::IsFull()':
UnsortedListType.cpp|35|error: expected type-specifier
UnsortedListType.cpp|35|error: expected unqualified-id before 'exception'
UnsortedListType.cpp|35|error: expected ')' before 'exception'
UnsortedListType.cpp|35|error: expected '{' before 'exception'
UnsortedListType.cpp|35|error: 'exception' was not declared in this scope
UnsortedListType.cpp|35|error: expected ';' before ')' token
Everything I can find on this error says the problem is either an extra semicolon or a missing semicolon, either in the header or this file. I can't find an instance of either. And if I remove the try/catch block, it compiles fine.
Plus, if I catch an int, it compiles just fine:
template<class T>
bool UnsortedListType<T>::IsFull()
{
try { return false; }
catch(int exception) { return true; }
}
I can also catch(int) and it will compile just fine, but if I try to catch(std::bad_alloc) (i.e. with no "exception" variable name) it throws the same error listed above. Even if I try simply catch(std::exception) it fails to compile.
So now I'm stumped. I'm not an expert at C++ by any stretch, this is for a class, and I'm not sure how to get past this error.
Incidentally, here's the code from the non-generic version, which also compiles just fine, and is verbatim from the textbook I'm using (Dale, if anyone wonders):
bool UnsortedListType::IsFull() const
{
NodeType* location;
try
{
location = new NodeType;
delete location;
return false;
}
catch (std::bad_alloc exception)
{
return true;
}
}
I am using CodeBlocks 12.11 IDE on Windows 7 with the built-in GNU compiler.
Any help appreciated, and I'll be happy to post more code if requested, I just didn't want to fill the page up.
Many thanks in advance.
PS I should state, yes I am doing homework, but the homework doesn't call for me to make a template, I am choosing to go that route myself. Not sure if it has any relevance, but this is the first time I've used C++ templates, so just tossing that out there.
std::bad_alloc is defined in the header <new>, so you need to include that.
Also, it's better to catch exceptions by reference. Catching by value causes a copy, perhaps sliced, of the exception object to be made. Personally I make non-const reference a habit, allowing exception state to be added during handling, but most basic exception types are stateless so there's no practical difference between const & and non-const &.