Lua Tricks: Detect Accidental Global Creation

Learning Lua can be a little tricky. The idea of variables implicitly being global can be confusing for some people, so using new users often dropped the much-needed local keyword.  If you are concerned about accidentally creating globals there is a quick and easy check you can do you show you when/where you are creating them!

To implement this we are going to create a new metatable for the globals table.  If you didn’t already know, all globals in Lua are stored in a table called the “environment“.  It is accessible anywhere in Lua by accessing a table called “_G“.  The fact that all globals are stored in the same table allows us to take advantage of a nifty metamethod call __newindex.

__newindex – From lua-users.org
Control property assignment. When calling “myTable[key] = value”, if the metatable has a __newindex key pointing to a function, call that function, passing it the table, key, and value.

  • Use “rawset(myTable,key,value)” to skip this metamethod.
  • (If the __newindex function does not set the key on the table (using rawset) then the key/value pair is not added to myTable.)

This is exactly what we’re looking for!
[lua]
setmetatable(_G, {__newindex =
function(self, key, value)
if not Engine:AllowGlobals() then
Engine:StopWithError(“Invalid Global created”)
else — Set value normally
rawset(self, key, value)
end
end
})
[/lua]

With this setup, you can see what this example will do:

[lua]
— OK
local testVar1 = 5

— Not OK, invalid global
testVar2 = 17
[/lua]

 

You can handle the invalid global creation however you want.  In my case I called a function that would halt the game and present the user with an error where it occurred:Invalid Global

 

Another nice trick you can do is make a global function that will explicitly create a global.  This clearly outlines when you are creating a new global and can make your code a bit easier to follow.  A example of such a function looks like this:

[lua]
DeclareGlobal = function(name, value)
— Allow creation of our new global
Engine:SetGlobalCreation(true)

_G[name] = value

— Turn off global creation
Engine:SetGlobalCreation(false)
end

–[[ Example usage ]]
— Not OK
testGlobal = 5

— OK
DeclareGlobal(“testGlobal”, 5)
[/lua]

You can expand this idea to work with any table you’d like as well. While I won’t go into in this post, you could easily set up a system in which you must explicitly declare key/values in tables to help prevent erroneous variable creation.

Hopefully this can help a few people from bashing their head on their keyboard because of a few typos!

Read More

C++ Asserts: Harder, Better, Faster, Stronger

Asserts are awesome.  They are one item in a programmer’s toolkit that can be seriously under-utilized.  I have found them to be the most effective way to detect and fix erroneous results in my day-to-day programming.  In this post I am going to be exploring a few ways we can make our own assert macro a little bit more robust.

Note – Moving Forward with MSVC
Using preprocessor directives often varies from compiler to compiler.  In this example I am using Microsoft’s VC++ in VisualStudio 2013 but the features I will be using are supported in one way or another in any compiler worth using nowadays.

 

Naive Assertions

Most programmers can come up with a simple assert macro that works for them.  A first go at it might look something like this:

[cpp]
#define ASSERT(x) if(!x) { __debugbreak(); }
[/cpp]

This is pretty straight forward.  If x does not evaluate to true, then we will call the __debugbreak function.  This logic almost immediately fails in real-world usage though. Let’s walk through some good practices when dealing with assertion macros.

 

Parenthesize macro arguments

Consider the following test which checks two values or’d together:

[cpp]
ASSERT(true || false);
[/cpp]

This should always evaluate to true, and therefore not cause an assertion, but with our current assert it will fail.  It is clear when you look at how the macro expands:

[cpp]
if(!true || false) { __debugbreak(); }
[/cpp]

This is were you learn a lesson applicable to most macros you will ever write:  Always parenthesize your macro arguments.  After adding parenthisis our macro now takes complex conditionals with ease and correctness:

[cpp]
// Note the parenthesis in our if check
#define ASSERT(x) if(!(x)) { __debugbreak(); }

// Statement now expands to:
if(!(false || true)) { __debugbreak(); }
[/cpp]

 

Wrap macro logic in do-while loops

Writing a macro with any logic can be tricky. If you’re not careful, debugging macros can leave you scratching your head for hours. This next method can help alleviate some of those situations.
Let’s look at the following situation:

[cpp]
if(entity.IsPlayer())
ASSERT(entity.IsAdmin());
else
entity.Kill();
[/cpp]

Logically, this code is sound:

  • If the entity is a player, assert that they are an admin.
  • If the entity is not a player, kill them.

While you wont get any warnings or errors, this logic is contorted a bit by our expanded macro:

[cpp]
if(entity.IsPlayer())
if(!entity.IsAdmin()) { __debugbreak(); }
else
entity.Kill();
[/cpp]

Our macro subtly twists our logic against us.  By wrapping our macro logic in a do{ .. }while(0), we can stop this from happening:

[cpp]
// Newlines added for readability
#define ASSERT(x) do { \
if(!(x)) { __debugbreak(); } \
} while(0)

// Logic now expands to:
if(entity.IsPlayer())
do {
if(!(entity.IsAdmin())) { __debugbreak(); }
} while(0);
else
entity.Kill();
[/cpp]

 

Disable the ASSERT macro in release builds

Assertions are great because they are a quick and easy way to ensure that your program isn’t using erroneous data, but you don’t always want them.  Large projects that have hundreds of thousands of lines of code will have a lot of assertions (especially if you’re following rule #5 when writing safety critical code for NASA), so wouldn’t it be nice to have the ability to disable them?  Luckily, because our assertions are in a macro, we can disable them, leaving us with virtually no overhead from them.

Using preprocessor directives we can toggle our assertions with a #define like so:

[cpp]
#ifdef _USE_ASSERTS
#define ASSERT(x) do{ \
if(!(x)) { __debugbreak(); } \
} while(0)
#else
#define ASSERT(x) // Do nothing with X
#endif
[/cpp]

Let’s compile with asserts disabled using some of our previous code:

[cpp]
const bool success = entity.Kill();
ASSERT(success);
[/cpp]

You will most likely get a compiler warning somewhere along the lines of this:

[cpp]warning C4189: ‘success’ : local variable is initialized but not referenced[/cpp]

While the best option would be to remove/rework code like this, one way to get around this is by casting your macro argument to void like so:

[cpp]
// Note that we still use a do-while
#define ASSERT(x) do { (void)(x); } while(0)
[/cpp]

While this does removed the ‘unused variable’ warning for most compilers, it can still have side-effects.  For example, if we are asserting the return value of a function directly, it will still call this function. A nifty trick to get around that is to use the sizeof operator on your argument:

[cpp]
// Note that we still use a do-while
#define ASSERT(x) do { (void)sizeof(x); } while(0)
[/cpp]

This works because the sizeof operator is guaranteed to not evaluate the arguments to it.  This should also allow the compiler to optimize the small remains of our disabled assertions.

Note – Executing needed code in an assertion
When we disable our asserts, the value inside of the assert is no longer evaluated or executed.  If we changed the code snippit above to not use a local variable, our code would not execute as planned:

[cpp] ASSERT(entity.Kill());[/cpp]

This entire line would be skipped.  You will inevitably make this mistake and experience this behavior when switching to a release build and then you will never make this mistake again.

 

Spiff up your results

Up to this point we have been under the assumption that we are always going to be attached to a debugger while running the game, so just calling __debugbreak is sufficient.  If ever want to get info from an assert when not actively attached to a debugger, we’ll need to add some output to tell us what went wrong.  Luckily for us most compilers have predefined macros that will help us report this info very easily.

The first thing we will want to do is change our behavior when we are asserting.  I’ve always found it easiest to call a function in the case of an assert so you can keep the size of your macro to a minimum.  Something like this will do nicely:

[cpp]
namespace Assert
{
void HandleAssert(const char *message,
const char *condition,
const char *fileName,
long lineNumber);
}
[/cpp]

In the definition for our HandleAssert function we can do pretty much any logging we want. I personally prefer a a pop-up message box with some information, but here is a bare-bones version that works just fine:

[cpp]
void Assert::HandleAssert(const char *message, const char *condition, const char *fileName, long lineNumber)
{
std::cerr << "Assert Failed: \"" << message << "\"" << std::endl; std::cerr << "Condition: " << condition << std::endl; std::cerr << "File: " << fileName << std::endl; std::cerr << "Line: " << lineNumber << std::endl; std::cerr << "Application now terminating"; } [/cpp]   Now we must fix our macro to call HandleAssert. We will be using a few predefined macros for this:

  • __FILE__ – Current file we are in.
  • __LINE__ – Current line we are on.
  • #x – Stringify ‘x’.  This allows us to display the exact conditional that caused our assertion.

A full list of predefined macros for MSVC can be found here.

Using these macros, our assert starts to look something like this:

[cpp]
#ifdef _DEBUG
#define ASSERT(x) do{ \
if(!(x)) {\
Assert::HandleAssert(“Assertion!”, #x, __FILE__, __LINE__); \
__debugbreak(); \
}\
} while(0)
#else
#define ASSERT(x) do { (void)sizeof(x); } while(0)
#endif
[/cpp]

Note that we left our __debugbreak call outside of our helper function.  This will cause the compiler to break on the line we put our assert on instead of breaking inside of our helper function.

Another useful option is to add specific messages to our asserts.  This is trivial to do in our case because we have an additional parameter that we pass to our HandleAssert function.  The cleanest was to do this is to create another macro that accepts two arguments: one for the conditional and one for the message to display if the assert fails.  Here is our entire macro which includes our newly added custom message assert ASSERT_MSG:

[cpp]
#ifdef _DEBUG
#define ASSERT_MSG(x, msg) do{ \
if(!(x)) {\
\
Assert::HandleAssert(msg, #x, __FILE__, __LINE__); \
__debugbreak(); \
}\
} while(0)

#define ASSERT(x) do{ \
if(!(x)) {\
Assert::HandleAssert(“Assertion!”, #x, __FILE__, __LINE__); \
__debugbreak(); \
}\
} while(0)
#else // Disabled Asserts
#define ASSERT(x) do { (void)sizeof(x); } while(0)
#define ASSERT_MSG(x, msg) do { (void)sizeof(x), (void)sizeof(msg); } while(0)
#endif
[/cpp]

Go forth and assert

With this setup you’ll have a pretty decent assert macro for you to use. It is also pretty easy to add extra features as needed.  Here are a few I’ve used in the past that can be helpful:

  • Define a different definition for HandleAssert based on what type of build you are using.  Shipping builds should probably use a graceful crash handler/error reporter, while debug should give you the dirty details.
  • Make the macros cross-platform.  It is easy to extract the needed macros (file/line number, debug breaking) into their own user-defined macros which you can define for each platform you build on.
  • Allow for different assertion behavior.  You can have HandleAssert return a value in which you specify whether or not you want the process to halt.  This can be helpful if you want to give the user an option to try to continue running the process.  This is generally discouraged because you’ve probably already entered undefined behavior, so a crash is likely anyways.

Here is the source for the completed example if you’re interested: Assert.zip

Leave a comment if you have any other cool tricks with asserts.  They’re silly looking and stupid-easy to write, but damn are they awesome.

Read More

C++ Macro-defined Enums

I picked up a nifty trick recently for defining enumerations in C++ using some funky syntax that takes advantage of user-defined macros.

Let us recall how simple C++ macros work.

[cpp]
#include // std::cout, std::endl

#define MYOPERATION(x, y) (x + y)
int main(void)
{
std::cout << MYOPERATION(3, 2) << std::endl; // '5' return 0; } [/cpp] This will output a value of 5, as MYOPERATION is replaced by the preprocessor with its contents which adds the two variables.  Our MYOPERATION macro does not have to add, as we could define it to do whatever we wish. We also have the ability to change what our MYOPERATION macro means mid-file.

[cpp]
#include // std::cout, std::endl

#define MYOPERATION(x, y) (x + y)

int main(void)
{
std::cout << MYOPERATION(3, 2) << std::endl; // '5' #undef MYOPERATION #define MYOPERATION(x, y) (x * y) std::cout << MYOPERATION(3, 2) << std::endl; // '6' return 0; } [/cpp] Elegance aside, this feature can help us leverage the preprocessor to do some nifty stuff for us. Consider a situation in which we need an enum for different types of fruit. While having this enumeration is nice, we also need a way to output our fruit enum to the user.  A naive solution could be as so: [cpp] enum Fruit { Banana, Apple, Strawberry, Pineapple, Snozberry, Count }; const char *FruitStrings[] = { "Banana", "Apple", "Strawberry", "Pineapple", "Snozberry", "Invalid" }; [/cpp] While this method certainly does work, it isn't very expandable. If we add a new fruit to the enum, we must add a matching string to our array at the correct spot. Wouldn't it be nice if we could somehow take our enumerated values and turn them all into strings? They are (for the most part) the same text after all. Well good news everyone, we can! Using the fact that we can redefine macros, we can leverage the preprocessor to generate both the enum and the array of strings for us. It is trivial to create two separate macros that generate these for us as long as we define our data correctly. The first step we need to do is define all of our fruit. This will have to be in its own file with nothing else in it: [cpp title="FruitDeclarations.h"] FRUIT(Banana) FRUIT(Apple) FRUIT(Strawberry) FRUIT(Pineapple) FRUIT(Snozberry) [/cpp] [panel style="panel-warning"] [panel-header] Note – Resist the urge to use header guards
[/panel-header]


Good programming practices make us want to use a header guard in all of our headers, but if we want to use our enum declaration header for more than one place then we must leave it out!

[/panel]

On its own, this file looks quite wonky, but with preprocessor macros in-mind it will start to make sense. What we have done is called a macro called FRUIT on all of our tasty fruit (Note: We did not include our count in this). Now all we have to do is write the macros that will take in the data. These should be in a separate file from the declarations of our enum values:

[cpp title=”Fruit.h”]
// Fruit Enum
#define FRUIT(x) x,
enum Fruit
{
#include “FruitDeclarations.h”
Count
};
#undef FRUIT
[/cpp]

This macro tells the preprocessor to append a command to our fruit names. Since they were all defined in a row in FruitDeclarations.h, this builds a nice enumeration for us. This is also a nice reminder that you can include header files in all sorts of cool places. We also need to add our count value onto the end of the list, as we did not add it in the declarations file.

By redefining the FRUIT macro we can generate our list of strings with the same data set:

[cpp title=”Fruit.h”]
// Fruit Strings
#define FRUIT(x) #x,
const char *FruitStrings[] = {
#include “FruitDeclarations.h”
“Invalid”
};
#undef FRUIT
[/cpp]

If you are unfamiliar with preprocessor directives, the ‘#‘ character allows us to ‘stringify’ an argument of a macro. We use this to turn all of our fruit names into C-strings in our array. Also notice how we are adding an additional string on the end of the array. This allows us to handle the user passing our fruit count into the array.

Edit – Good practices with extern
A friend has reminded of me a best practice when it comes down to declaring/defining arrays in header files.  When defining an array in a header file, it is entirely possible for the compiler to instantiate said array in every module that includes our header.  To ensure we only instantiate our array once, we can use extern in our header to declare the array, and then define it in a .c/.cpp file.  The fix looks something like this:

[cpp title=”Fruit.h”] // Fruit Strings Declaration
extern const char *FruitStrings[Count+1];[/cpp]

Note: We must define the length of our array using our enum value ‘Count’ as the compiler doesn’t have our initializer list to deduce the length of the array. We must add one onto it for the additional ‘Invalid’ string, as the enumeration values are 0-based.

[cpp title=”Fruit.cpp”] #include “Fruit.h”
// Fruit Strings Definition
#define FRUIT(x) #x,
const char *FruitStrings[] = {
#include “FruitDeclarations.h”
“Invalid”
};
#undef FRUIT[/cpp]

And there you have it. Using this method you can easily create all sorts of automatically generated data along-side enumerations in C/C++. Please let me know in the comments below if you find any more cool tricks you can do with this method!

Read More

Chronomancers | Segment Prototype

Our team, Jam Good Games, just had our Segment Prototype milestone in our GAM300 class.  Here are a few highlights from the milestone:

Notable Editor Features:

  • Written in C++ w/ wxWidgets for GUI
  • Supports custom Lua components with full reflection of C++ classes
  • Features rotate, scale, and translate gizmos w/ multi-selection
  • Component-based property editing at run-time
  • In-engine scripting documentation w/ auto-complete

Read More