Introduction
This document is a collection of some of the interesting constructs that are possible in C
and C++. While "nice", these features may not serve to increase code clarity but to
obfuscate it. Your mileage may vary.
Playing with the C stack
Parameters on the stack appear in memory with the leftmost item at the lowest memory location.
Thus you can get a pointer to your functions stack frame, and walk the parameter list, or even
cast your stackframe to a struct that can be passed to other functions.
The first sample demonstrates how to retrieve the pointer to any variable parameters passed
to the function.
int __cdecl printf(char const* pszFmt,...)
{
char buf[1024];
return wvsprintf(buf,pszFmt,&pszFmt+1);
}
This sample demonstrates how the functions passed to a function can be passed to another
function.
BOOL InvalidateRect(
HWND hwnd,
LONG left,
LONG top,
LONG right,
LONG bottom,
BOOL fErase)
{
return InvalidateRect(hwnd,(LPRECT)&left,fErase);
}
Constructing variable length structs
A trick to using structs that have a variable sized member is to use an overloaded operator
new to allocate space for the struct.
struct string {
int cb;
char sz[];
void* operator new(int cb, int cbExtra){
return new char[cb+cbExtra];
}
};
Now contrast the following code to create such a struct:
...
string* pStr = new(strlen(pszInString)) string;
...
The "C" method of working with variable sized looks like this:
...
string* = (string*)new char[sizeof(string) + strlen(pszInString)];
...
Working with big endian data
A have always favored little endian number representation over big-endian, which why I was
saddened when I found that TCP/IP, and most internet protocols (such as SSL3) use a big
endian representation for numbers. Following is the type of construct I use when I need
to work with a non-native data type in structs that I pull off of the network.
typedef unsigned char uint8;
struct uint16 {
uint8 n[2];
operator unsigned short(){
return ((unsigned short)n[0] << 8) + n[1];
}
};
Using a struct like this has two advantages:
- If a
typedef unsigned short
was used you could accidently use the number
in situations without converting it.
- The operator
unsigned short
ensures that the struct can be used as a normal
unsigned short where required.
Please send any comments or bug reports to me via
email. For any updates to this article, check my site
here.