While porting a project from Visual Studio 2005 to 2013, I came across this strange behaviour for which I cannot find an explanation. The context was about creating template specializations by including a certain header file multiple times, but changing preprocessor definitions before each include to basically generate a different class declaration.
I could narrow down the issue to the following situation:
gen.hpp
#ifdef ENABLE_GEN
#ifdef GEN_SWAP_ORDER // (1)
class Foo {};
#else
class Bar {};
#endif
#endif
main.cpp
#define ENABLE_GEN
#include "gen.hpp"
#define GEN_SWAP_ORDER
#include "gen.hpp"
int main()
{
Foo foo;
Bar bar;
}
This works as expected, i.e. both Foo and Bar are declared and usable in main().
Now, to cause the issue, change the #ifdef in the line marked by (1) to #ifndef, which should effectively only cause the order in which Foo and Bar are declared to be swapped. But instead, compilation then fails:
1>c:\path\to\main.cpp(10): error C2065: 'Bar' : undeclared identifier
1>c:\path\to\main.cpp(10): error C2146: syntax error : missing ';' before identifier 'bar'
1>c:\path\to\main.cpp(10): error C2065: 'bar' : undeclared identifier
The preprocessed file looks like this (stripped some whitespace):
#line 1 "c:\\path\\to\\main.cpp"
#line 1 "c:\\path\\to\\gen.hpp"
class Foo {};
#line 8 "c:\\path\\to\\gen.hpp"
#line 10 "c:\\path\\to\\gen.hpp"
#line 4 "c:\\path\\to\\main.cpp"
int main()
{
Foo foo;
Bar bar;
}
My question is: Am I missing something? Is this expected behaviour for some reason? Is it a compiler setting/bug that makes Visual Studio skip the header contents (including the #else part) a second time when it thinks it has a header guard (because of the #ifndef)?
Thanks!
This is MS Connect issue 800200 as per dyp's comment, and was fixed in VS2013 RTM.
Related
Here's a minimal case. Compile with "/openmp" on Visual C++ 2015.
#include <vector>
void main()
{
bool foo = false;
#pragma omp flush (foo)
std::vector<int> bar;
}
I get:
C2146 syntax error : missing ';' before identifier 'bar'
C2275 'std::vector<int,std::allocator<_Ty>>' : illegal use of this type as an expression
C2065 'bar' : undeclared identifier
If I comment out the #pragma, the error goes away.
If I replace std::vector with int, the error goes away.
If I put a ; on a line by itself below the #pragma, the error goes away.
The concise answer to the question "Why doesn't this compile?" is "it's a compiler bug". The bug report at:
https://connect.microsoft.com/VisualStudio/feedbackdetail/view/2420614
has been closed as "fixed".... "this item has been fixed in the current or upcoming version of this product [Visual Studio 2015]".
I'm using Visual C++ 2010, and here's my code snippet:
std::set<int> s;
decltype(s)::value_type param = 0;
I got the following error message, anyone can help me?
> error C2039: 'value_type' : is not a member of '`global namespace''
> error C2146: syntax error : missing ';' before identifier 'param'
This is a Visual Studio bug that was raised last year on Connect. It is issue 757545 ("Cannot use decltype before scope operator").
The issue has a workaround listed alongside it that is effectively the same as #iammillind's, except it uses std::identity that was removed from <functional> shortly prior to the publication of C++11, for whatever reason. (std::common_type with one template parameter is equivalent; std::remove_reference is the same in some cases.)
I see that with g++ 4.7.2 version, the code compiles fine. So it could be a compiler bug in MSVS.
For time being you can try below trick:
#ifdef COMPILER_BUG_STILL_THERE
template<typename T> struct Get { typedef T type; };
#define DECLTYPE(VAR) Get<decltype(VAR)>::type
#else
#define DECLTYPE(VAR) decltype(VAR)
#endif
Use it as:
DECLTYPE(s)::value_type param = 0;
Disclaimer: Ofcourse with this trick, you may have to use typename when inside templates. For that you can have 1 more macro such as #define TDECLTYPE(VAR) typename DECLTYPE(VAR)
I am using Visual Studio 2010 Express and I am getting the following errors for the file test.h, which when compiled outputs:
test.h(4): error C2061: syntax error : identifier 'test'
test.h(4): error C2059: syntax error : ';'
test.h(4): error C2449: found '{' at file scope (missing function header?)
test.h(18): error C2059: syntax error : '}'
The file test.h is described as follows:
#ifndef TEST_H
#define TEST_H
class test {
int a;
int b;
public:
test(int a, int b) {
this->a = a;
this->b = b;
}
int add() {
return 0;
}
};
#endif
The other file in the VS2010 project is test.c which is:
#include "test.h"
int main(int argc, char** argv) {
return 0;
}
I have a tried of multitude of ways to resolve this problem. Even if I define test.h as follows:
class test{
};
I still receive the same set of errors.
I saw a similar problem
https://stackoverflow.com/questions/7798876/strange-errors-when-using-byte-pbyte-instead-of-char-char-in-vs2k10-wdk-envi
with no response.
I will be really grateful if someone could please point out how to resolve these errors.
Thanks,
The Microsoft compiler supports both C and C++ languages, but they are not the same and need to be treated differently (for example class is no keyword in C and thus ultimately causes the error your get). So it has to somehow "know" what kind of language (C or C++) it is dealing with when compiling a source file (and thus also processing the includes).
It thinks you are trying to compile a C language file (because it has the file extension .c), while you are actually using the C++ language. Rename your file to have one of the file extensions the Microsoft C/C++ compiler recognizes as C++: .cpp, .cxx or .cc.
Alternatively, if you cannot rename the file, you can also use the /Tp command line option of cl.exe to force it to treat the file as a C++ file (for completeness /Tc would force the C language).
As the title says, I'm getting a compiler error in a VS2008 C++ program. I'm not sure how better to describe my problem than in code. The following compiles unless I uncomment the TEST line.
#include <windows.h>
#include <iostream>
using namespace std;
//#define TEST //<-- uncomment for error
#ifdef TEST
void test(void* interface)
{
return;
}
#endif
int main()
{
cout << "Hello World" << endl;
system("PAUSE");
return(0);
}
When uncommented I get the following errors:
1>main.cpp(7) : error C2332: 'struct' : missing tag name
1>main.cpp(7) : error C2144: syntax error : '<unnamed-tag>' should be preceded by ')'
1>main.cpp(7) : error C2144: syntax error : '<unnamed-tag>' should be preceded by ';'
1>main.cpp(7) : error C2059: syntax error : ')'
1>main.cpp(8) : warning C4094: untagged 'struct' declared no symbols
1>main.cpp(8) : error C2143: syntax error : missing ';' before '{'
1>main.cpp(8) : error C2447: '{' : missing function header (old-style formal list?)
This is unmanaged code, so I'm not sure what the issue with the word interface is. Is there any way to get this code to compile as is, or do I have to change every instance of the term interface to something else?
Thanks!
If your code needs to include Windows.h then you should avoid using the name interface as it's reserved for the use that the Windows SDK has reserved for it (essentially it's a synonym for the keyword struct). There are probably hacks to work around that problem (you could #undef interface after including the SDK headers), but you should probably avoid using that identifier.
The word interface is reserved by MSVC++, as it is a non-standard keyword added by Microsoft Compiler, which is used to define interface in MSVC++.
So use a different name for the parameter, something like this:
#ifdef TEST
void test(void* test_interface)
{
return;
}
#endif
I'm using Visual Studio 2008 Express Edition to compile the following code in a header file:
bool is_active(widget *w);
widget is defined earlier as,
typedef void widget;
The compiler complains with the error:
>c:\projects\engine\engine\engine.h(451) : error C2061: syntax error : identifier 'is_active'
1>c:\projects\engine\engine\engine.h(451) : error C2059: syntax error : ';'
1>c:\projects\engine\engine\engine.h(451) : error C2059: syntax error : 'type'
I get similar errors for all other functions returning bool.
NB. The following compiles fine:
void widget_activate_msg(widget *g, message *msg);
Why would this give a compiler error?
Some people have requested I post the code - here it is:
Line 449: widget * widget_new_from_resource(int resource_id);
Line 450: void widget_delete_one(widget *w);
Line 451: bool is_active(widget *w);
EDIT - this is now fixed:
#BatchyX commented below about whether I was using C or C++. What I didn't know was that Visual C++ 2008 will compile any file by default (but you can override this setting ) with the .c extension as C and those with .cpp as C++. ( the error was caused when compiling a .c file including "Engine.h" ).
Most likely, something above this line has a syntax error. Did you forget }s or ; after a class declaration ?
Also make sure you are using C++ and not C. C doesn't have a bool type. If you're using C, then use an int instead.
I'm guessing that it's not possible to typedef void. Why not use typdef void* WidgetPtr; and then bool is_active(WidgetPtr w);
EDIT: Having done some tests it's clear that void can be typedef'd and it can be part of the function signature as shown in the users code. So the only other solution is that whichever header has declared typedef void Widget is not included within the file that declares/defines the function or you're having a #def guard statement clash.