June 1999 Obfuscated C++

.
Last Month's Obfuscated C++

Last month we asked you to explain the semantics of the function f in the following code:
bool n(void* s) {
	return ((*(long*)s-0x01010101)&~(*(long*)s)&0x80808080);
}

int f(char* p) {
	int r = 0;
	while(!n(p))r+=4,p+=4;
	while(*p++)++r;
	return r;
}
This code, which was inspired by an example in Don Libes' book Obfuscated C and Other Mysteries,1 is a strange implementation of strlen(). Function f returns the length of the null-terminated string passed in as an argument. It does this through repeated calls to the function n, which returns true if any of the first four bytes pointed to by its argument is null. (Function n could have taken a char* argument, of course, but it's slightly more confusing if we declare it to take void* and depend on the implicit conversion from char* to void* to resolve the call.)

The first loop in f steps through the function, four bytes at a time, until it reaches a block of four bytes that contains a null. The next loop then steps through that block one byte at a time to finish the calculation of the length, which is returned in r.

Of course, on every machine I've tried this on, the native strlen is much faster than the previous implementation, even if we make n an inline function. The reason is that most current C++ libraries have strlen implementations that are heavily optimized (often taking advantage of special assembly instructions). Make sure you test every "clever" algorithm like this to make sure that the extra complexity doesn't swamp the performance gain of the algorithm as it does here!

This function assumes that a long corresponds to four bytes, which isn't always the case; but we warned you last month that the example wouldn't run on all platforms.



This Month's Obfuscated C++

This month we'll take a simple algorithm and use confusing naming, indentation, and coding to obfuscate it. We'll start with a simple template class that holds an integer matrix:
template  struct m {
	int _[A][B];
};
We've left off the constructor to allow initialization using the aggregate rules, for example:
m<2,3> x = { 1,2,3,4,5,6 };
Given this template, explain the semantics of the following template function:
template 
m
f(const m& x, const m& y) {
	m rc;
	for(int c=R-1;c>=0;--c)
	for(int r=0;r
Reference
1. Libes, D. Obfuscated C and other Mysteries, John Wiley & Sons, New York, NY, 1992.

 



Rob Murray is Director, Engineering at the Irvine office of Net Explorer, an object-oriented software consulting company based in Houston, TX. He has taught C++ at technical conferences since 1987, and is the author of C++ Strategies and Tactics. He was the founding editor of the C++ Report and can be contacted at [email protected].


Quantity reprints of this article can be purchased by phone: 717.560.2001, ext.39 or by email: [email protected].