Handmade Hero»Forums»Code
Dylan Courville
2 posts
Error on "*NewKeyboardController = {};"
Edited by Dylan Courville on
When I open up the downloaded source code, everything compiles fine except the line
1
*NewKeyboardController = {};
in win32_handmade.cpp. I've always just changed it to
1
2
 game_controller_input ZeroController = {};
*NewKeyboardController = ZeroController;

Although this works fine, it's a bit tedious, but more importantly, I don't really understand why Casey doesn't have to do this....

In case it helps, the compiler error is error C2059: syntax error : '{'

EDIT: I just figured out why this was happening -- I was using Visual Studio Express 2013, which for some reason doesn't support the same language features as the other versions. If anyone's having similar issues, make sure to download the Community Edition.
Simon Anciaux
1337 posts
Error on "*NewKeyboardController = {};"
Edited by Simon Anciaux on
I've got the same thing compiling casey's code with Visual Studio 2012.
There are a few things that are not supported by VS2012 and maybe this is one of them (initializer list after the declaration of a variable).

1
2
3
4
game_controller_input inp = { 0 }; // Works.

game_controller_input inp2;
inp2 = { 0 }; // Doesn't work.

I also have to define my own roundf function (apparently the float version doesn't exist in VS2012).

If you're compiling with VS2013 I've no idea what's happening.
Mārtiņš Možeiko
2559 posts / 2 projects
Error on "*NewKeyboardController = {};"
This specific syntax requires C++11 support. VS2012 is not good with C++11.
Alternatively you can do something like this:
1
ZeroMemory(NewKeyboardController, sizeof(*NewKeyboardController));

And create ZeroMemory function that will write 0 to passed buffer.
Or use memset if you are OK to use C runtime:
1
memset(NewKeyboardController, 0, sizeof(*NewKeyboardController));
Patrick Lahey
67 posts
Error on "*NewKeyboardController = {};"
Edited by Patrick Lahey on
Yeah, this is really sad.

Valid C99 (or later)

// right hand side is a "compound literal" (anonymous initialized struct)
*NewKeyboardController = (game_controller_input){};

Valid C++11 (or later)

*NewKeyboardController = {};

Sigh...
Casey Muratori
801 posts / 1 project
Casey Muratori is a programmer at Molly Rocket on the game 1935 and is the host of the educational programming series Handmade Hero.
Error on "*NewKeyboardController = {};"
Yes, if you ask me the whole situation is rather sad because there should just be an f'ing in-language construct for "clear to zero". It bugs me that that's not in there. I don't even know that {} really has anything to do with clearing to zero, it's just what happens when you haven't defined any default values or constructors or whatever, right... I think it's behavior actually is much more complicated if you start using other C++ features that we just don't happen to use, so we can use it as "clear to zero" even though that's not what it actually means :(

- Casey
Dylan Courville
2 posts
Error on "*NewKeyboardController = {};"
Updated the OP with the fix--turns out I just had to switch to Community Edition from Express (because for some reason Express doesn't support the same syntax).
Mārtiņš Možeiko
2559 posts / 2 projects
Error on "*NewKeyboardController = {};"
Edited by Mārtiņš Možeiko on
Hm, that should not be the problem. Express edition, Community Edition, Professional, Ultimate - they all use same compiler. Only differences are in IDE. Compiler is the same.

Express edition (2013) should support C++11 uniform initializer syntax just fine.
Patrick Lahey
67 posts
Error on "*NewKeyboardController = {};"
Edited by Patrick Lahey on
As long as we stick to aggregates (basically C structs), the new C++ list initializer stuff will do what we want (zero out the struct).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
struct my_type 
{
    int X;
};

my_type a;

a = {};        // This is equivalent to
a = my_type{}; // this: create anonymous "aggregate initialized" aggregate
               // (similar by weaker than (my_type){} from C99)


The C++ equivalent to C's compound literals is weaker because (for better or worse...) C allows you to take the (non-const) address of the anonymous object. Although that is ripe for abuse it can come in handy when you just need to pass a pointer to a struct into a function and either 0 initialized is a good input or you don't care about the output:

1
2
3
int UsefulFunction( my_type * a );  // function prototype

int Result = UsefulFunction( &(my_type){} ); // C99, be careful!


Casey is right that the rules change completely once you move away from aggregates. Fred got nailed by this a few days ago in the C struct initialization to 0 with "= {};" thread. As soon as you do anything that makes it a non-aggregate, boom...