Satan's Syntax
A lot of us picked up bad habits from our earlier days of coding that are still with us today. This article discusses how we can use some quirks of C's syntax to overcome these habits and write more efficient code.
[size="5"]Remember The Return Types
My first example of this "template programming" will involve the formatting output function sprintf. It is not unusual to write code such as:
sprintf(str1, "Old v=%d\t",v);
/* Some code that plays with v */
sprintf(str2, "New v=%d",v);
strcat(str1, str2);
printf(str1);Most instances of sprintf use a temporary string as the first parameter. This is the template that becomes engrained: "sprintf requires a temporary string". Whereas a better template would be a syntactical one, "sprintf requires a pointer to a character [array]". This is a reminder that we could, instead, use a function that returns a char * as our first parameter, saving a temporary buffer. For example:sprintf(str, "Old v=%d\t",v);
/* Some code that plays with v */
sprintf(strchr(str, '\0'), "New=%d",v);
printf(str);You should be prudent in using pointers directly, to avoid deferencing a NULL. In this case, strchr(str, '\0') is always valid thanks to the first sprintf. There is also a hidden bonus with sprintf - it returns the number of characters written into the buffer - which can save a call to strlen! Check your libraries. You might get lucky!To take another example, if the reason for getting a string is to determine its length is valid for some operation, you might write:
len = strlen(GetFileName());
if (len > 0)
; /* File name is not null */However, if all you're going to do is check len against zero, why not write:if (GetFileName()[0] != '\0')
; /* File name is not null */This time, not only do we save ourselves another temporary buffer (which is quite common, seeing as we use the result directly - it also eliminates the extraneous copy that usually follows), but we also show understanding for the data being returned (that a NULL-length string starts with '\0'), and we also remove the strlen overhead. Note that the same result could be achieved with the equivalent code:if (*GetFileName () != '\0')
; /* File name is not null */As a string is simply a structure (of type char *), you could also use this method with functions that return whole structures, C++ classes or pointers to them, and just isolate the element you want. For example:struct POINT GetCurrentPos(void);
int y;
y = GetCurrentPos().y;or,printf(GetDevice()->pName);The compiler is likely to create the structures as temporary variables, and pass their pointers as hidden parameters, so you need not worry about the overhead of copying structures to and from the stack.Just as a side point, remember the lessons that say "you can't return a string from a function"? Well. You can. Of sorts. By creating a structure of type STRING consisting of one character array called str, for instance, you can return STRING from a function, referencing it in the same manner.
struct STRING { char str[256]; };
struct STRING GetName(void)
{
.
}
printf(GetName().str);In the real world, this method offers little or no benefit to passing the string in as a pointer, but it does save the programmer creating temporary variables.[size="5"]Expressions
Function calls are just expressions. If they return a type (excluding void, which isn't really a type) then you can use them anywhere you would use a normal expression, like a while loop. This allows entire loops and the like to be short-circuited quickly, taking advantage of C's lazy evaluator (see sidebar).
while (1 && GetNextLine(&str))
;Changing the 1 to a 0 causes the whole expression to evaluate to 0: The GetNextLine function does not get called, and the loop never executes. I often use this method to remove long winded if statements from experimental code:if (1
&& ComplicatedExpression1
&& ComplicatedExpression2
&& ComplicatedExpression3
)
;By making the 1 a global, or static, variable, I can then remove the code during program execution with the debugger, or change it with a special menu option, allowing me to test different section on a single compile.[size="5"]End
I hope there's a few new ideas for you there. I neglected to mention code could also be removed with
/*
. code here .
//*/and re-inserted by adding a single / to the first line. But that's just too nasty![size="5"]Sidebar
C uses a lazy evaluator. This means it will only evaluate the necessary expressions to prove the expression is definitely TRUE, or definitely FALSE. So a line like,
if (fn1() && fn2() && fn3())
.Would evaluate fn1() first, but would only continue onto fn2() if it had too. Namely, if fn1() returned TRUE. If it returned FALSE, there is nothing the other functions could do to make the final expression TRUE. Most people know this instinctively from code snippets like:
if (ptr && ptr->Name)
printf(ptr->Name);This is different from Pascal.
Related Tutorials
Balancing Game Development and Creative Direction in Indie Production
A practical look at how indie developers can balance creative direction with hands-on game development. This article co…
My Unreal Engine Development Process: From Core Idea to Playable Build
A practical overview of my Unreal Engine development process, covering how I move from a core game idea to a playable b…
Introducing LaneGraph: The Ultimate Road Network Solution for Unity
Discover the power of LaneGraph, a lightweight and flexible lane-based navigation system for Unity. LaneGraph makes it…
Retargeting Mixamo Characters with Root Motion In Unreal Engine 5.4.
I have always found Retargeting Mixamo Characters To have Root Motion is a serious lengthy Tast, Recently I stumbled up…
How To Make A SIMPLE Main Menu In Unity
In this tutorial for unity, i go over how to make a simple main menu for unity, it's an unlisted video because i do not…
Guide to Gameplay Balance
A perspective on competitive gameplay balance, from a background of "shooter" sandbox design.
Discussion
More from Steve Goodwin
Comparing Shadow Mapping Techniques with Shadow Explorer
New Incentives and a Whole New Platform From The Intel AppUp developer program
The final installment in this series on Intel's AppUp program details additional incentives and opportunities for devel…
The Game Maker
This book excerpt contains the first chapter of the book that introduces beginning game developers to the Game Maker pr…
Discussion