Masterxilo Posted February 20, 2010 Share Posted February 20, 2010 Hi there This is some really strange problem I just noticed. Try compiling this class which creates a default instance and has a function with an enum-type argument with default value: MyClass.h #pragma once enum MyEnum {EN_1}; class MyClass { void foo(MyEnum e = EN_1) {} void bar(int e = 345) {} } extern myClassInstance; MyClass.cpp #include "MyClass.h" MyClass myClassInstance; The compiler will complain about "myClassInstance" having no type (and says it can't assume default-int). Obviously, the class declaration somehow get messed up in a way that doesn't allow the declaration of instances right at the end anymore. This appears to be caused by the default argument for foo(). If you remove the default enum argument ("= EN_1"), it'll compile fine. The default int argument works without problems... It also works if I declare the instance normally, not external, but I don't want that. The way around this issue is as simple as declaring the external instance after the class declaration. Like: class MyClass {... }; extern MyClass myClassInstance; But that shouldn't be necessary, should it? What do you think? I guess that's an msvc compiler bug. Where to report these? Oh, and btw. I noticed there's already a SP1 for msvc 2008 express. Do I have to download that update myself somewhere or did M$ update take care of it? I'm not quite sure if it's already installed, the info dialog says "Version 9.0.xxxxxx... SP", but not SP1 Quote Hurricane-Eye Entertainment - Site, blog. Link to comment Share on other sites More sharing options...
Canardia Posted February 20, 2010 Share Posted February 20, 2010 I think it's bad programming style to put anything after the final } of the class definition. Sometimes you create unwanted self-launching global variables with that, which should not be launched before other things have been initialized. I would not create any global variables (=objects), but keep them inside the main() function scope, and use class pointers inside classes if you need one class to talk with another. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Masterxilo Posted February 20, 2010 Author Share Posted February 20, 2010 That default instance is there to avoid using the commands statically and to not having to deal with that utility class' creation/initialization and deletion/termination. Quote Hurricane-Eye Entertainment - Site, blog. Link to comment Share on other sites More sharing options...
Rick Posted February 20, 2010 Share Posted February 20, 2010 That default instance is there to avoid using the commands statically and to not having to deal with that utility class' creation/initialization and deletion/termination. Use a singleton to replace a global object variable. This creates itself and destroys itself automatically and only the one method is static. class MyClass { private: MyClass(void){} public: static MyClass& Instance() { static MyClass myClass; return myClass; } void RunMe(){} }; MyClass::Instance().RunMe(); Quote Link to comment Share on other sites More sharing options...
Masterxilo Posted February 20, 2010 Author Share Posted February 20, 2010 That does the same and looks "uglier" to me. I prefer MyClass.foo(); (I usually name helper classes CMyClass and the default instance MyClass) over MyClass::Instance().foo(); Though that gives the advantage of being able to decide when to create the instance (it'll only be created at the first call)... Still, the code I posted should work the way it is and it doesn't -> compiler bug. Quote Hurricane-Eye Entertainment - Site, blog. Link to comment Share on other sites More sharing options...
Rick Posted February 20, 2010 Share Posted February 20, 2010 That does the same and looks "uglier" to me. As you said you can control when it gets created so it's not the same. I find this needed when using LE because if your class has any sort of LE commands you want to make sure LE is initialized before you can do anything in the constructor of your global class. I actually agree that the syntax is kind of crappy but it's a small price to pay for the benefits it gives. Would be better if you could override the dot operator to return the static instance. Would look better and the compiler should be able to know the difference between a class name and a class instance, but I don't think you can override the dot operator. But yeah, I notice this must be a bug. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.