forward declaration compiler error in a struct in C++ - c++

This compiles in Visual C++ 2010.
It does not compile und MINGW.
struct nextifcondinfo
{
hash_map <string, nextifcondinfo> next;
int action;
};
I get an error message:
Description Resource Path Location Type
forward declaration of 'struct nextifcondinfo' C/C++ Problem
Can you tell me what switches to use in mingw to solve? Or do you have any other ideas?

I don't believe your code is supposed to compile but it does depend on the hash_map implementation. Looks like you've been lucky with VC++ and unlucky with MinGW.
To solve use pointers, for instance
struct nextifcondinfo
{
hash_map <string, nextifcondinfo*> next;
int action;
};
You could use smart pointers as well.

Related

Use of std::deque and clang compiler [duplicate]

This question already has an answer here:
Why C++ containers don't allow incomplete types?
(1 answer)
Closed 6 years ago.
It seems that std::deque does not allow to use it in a recursive way with clang on osx when not using libstdc++ (10.9+ target)
#include <deque>
struct node { std::deque<node> childs; };
int main() {
node n;
}
This simple code compile with clang only if I set MACOS_DEPLOYMENT_TARGET=10.8 (because the clang compiler links with libstdc++) but it gives a lot of errors if I try to compile with libc++ (default c++ target on 10.9+), while with gcc 4/5 it works without problems...
It's a compiler bug or the standard does not allow this? It's seems a quite obvious use of a container...
In general, you should not expect this code to compile. To be sure that it compiles with any standard-compliant compiler you must use an extra level of indirection in one of the following or similar ways:
struct node { std::deque<node> *children; };
struct node { std::unique_ptr<std::deque<node>> children; };
struct node { std::deque<node*> children; };

Getting errors because compiler confuses static enum class between C++11 and Managed C++

I have recently migrated a Managed C++ project from Visual Studio 2010 to 2013.
Inside the definition of a class, I have:
static enum class ItemType
{
SHOP=IDS_SHOP,
PAGE=IDS_PAGE,
PHOTO=IDS_PHOTO
};
static bool EnumTryParse(CString sItemType, ItemType& refItemType)
{
System::String^ sType = gcnew System::String(sItemType);
return System::Enum::TryParse(sType, refItemType);
}
Trying to compile it is giving me errors. The reason seems to be that 2013 version uses C++11 behind the scenes and it confuses the Managed C++ enum class with the C++11 enum class.
What is the proper way to adapt my code to the new version?

Curiously Recursive Template Pattern in GCC 3.4 (MoSync to be exact)

I'm currently trying to write an Artemis like game component/entity system in C++. I was planning on getting this system to work with a cross platform tool for writing applications on Android and iOS called MoSync.
Unfortunately MoSync currently uses an old version of GCC and when porting the library that I had been testing in Visual Studio, I got a whole bunch of errors. Most of these I could solve, but there is one bug with templates that I can't get my head around.
I wrote a small example
template <typename T>
struct Base
{
static int type;
};
struct Derived : public Base<Derived>
{
};
template <typename T>
int Base<T>::type(-1);
extern "C" int MAMain()
{
Derived d;
d.type = 0;
}
My library uses the Curiously Recursive Template Pattern for defining Components. This example compiles fine in GCC 4.4 and Visual Studio 2010. However when I try to compile this in MoSync (which uses GCC 3.4.6) I get this linker error
C:\MoSync\workspace\pede\main.cpp: Error: Unresolved symbol '__ZN4BaseI7DerivedE4typeE',
Is there a workaround to get this to work in this compiler, or will I have to find another way to define my Components?
Edit*
In fact I can make this error occur with an even simpler example:
template <typename T>
struct Component {
static int t;
};
template <typename T>
int Component<T>::t(-1);
extern "C" int MAMain()
{
Component<int>::t = 0;
}
Gives this error
C:\MoSync\workspace\Components\main.cpp:9: Error: Unresolved symbol '__ZN9ComponentIiE1tE',
I guess this might not have anything to do with the Curiously Recursive Template Pattern at all. What can I do to get this to compile under GCC 3.4.6?
According to this bug report on the gcc bugtracker, the problem is caused by specifying a default value in the static variable definition. The code should link if you remove the initialisation as so:
int Base<T>::type;
The bug report seems to have been resolved as not a bug. Despite this, your samples compile fine in GCC 4.4.
To work around this, you can use a class type with a constructor that will automatically initialise itself.
Does adding
int Base<Derived>::type(-1);
helps ?
gcc 3.4 is really starting to be old and don't coep well with template sorcery.

Is Visual C++ correct when it refuses this template-"dependent" based enum?

Code:
#ifdef _MSC_VER
# pragma warning( disable: 4480 ) // enum base as "nonstandard extension"
#endif
enum ShouldBeFine: char { hola };
enum Choice { a, b, c };
template< Choice c > struct Traits;
template<> struct Traits<a> { typedef char Type; };
template<> struct Traits<b> { typedef wchar_t Type; };
template<> struct Traits<c> { typedef long Type; };
template< Choice c >
struct Blah
{
enum X: typename Traits<c>::Type {};
};
int main()
{}
Only after a Herculean effort to file a bug report with Microsoft, did it occur to me that maybe Visual C++ is correct to refuse it, and g++, which compiles the above fine, is maybe wrong?
EDIT Details: the code fails to compile with Visual C++ 10.0 and with the preview of Visual C++ 11.0. Those compilers spit out some rambling error avalanche beginning with an alleged syntax error. The code compiles fine with MinGW g++ 4.4.1. Dani reports that it compiles fine with CLang. Unfortunately Comeau Online does not support this language feature, so it can't be decided in the way we often did for C++98, just give the code to Comeau.
If I am reading the grammar correctly, you are correct in that this should compile. enum-base is : type-specifier-seq, and type-specifier-seq seems to include pretty much any type name you can think of, including typename Traits<c>::Type. And all three specializations result in Type being integral, which is also required of the enum-base. So That looks kosher to me.
This compiles fine in both clang and g++. In addition, template substitution should occur before the class and the enum inside is created, so it should not matter if its template dependent or not.
This has been fixed in the Visual C++ 11 Beta, released on February 29, 2012.
Note also that the warning you disabled--C4480--has also been fixed, so it is no longer incorrectly emitted in native C++ code when enum class is used.

Using Structs -- Odd Issue

Been awhile since I've used structs in C++.
Any idea why this isn't working? My compiler is complaining about DataStruct not being a recognized type but Intellisense in VC++ is still able to see the data members inside the struct so the syntax is ok...
Frustating. xD
struct DataStruct
{
int first;
};
int main(int argc, char **argv)
{
DataStruct test;
//test.first = 1;
}
Are you sure you are compiling the file as C++? If you compile it as C (i.e. if the file has a .c rather than a .cpp extension), you will have problems.
You are compiling as C code. C requires you to refer to it using the "Struct" keyword or typedef it. C++ does not.
You need to use struct DataStruct to refer to the struct.
Alternatively, you can typedef it as DataStruct if don't want to use the "struct" everywhere.