# Question about syntax (should be easy, right?)

• 09-10-2009
dandeibler
Question about syntax (should be easy, right?)
I've been scratching my head trying to figure this one out for a while and it's nearly impossible to google (though how I have tried). I'm trying to understand how the code:
Code:

char c = 1["3"];
or
Code:

char c = 2["22"];
is interpreted by a compiler. The result is that 1["3"] and 2["22"] somehow evaluate to the null character '\0', so the above code is equivalent to:
Code:

char c = '\0';
and
Code:

char c = '\0';
I first saw this syntax used in the 2004 International Obfuscated C Code Contest. {code} {hint}
...and I haven't seen it since. In the hint file, he explains that his program is obfuscated by (among other things) "standard tricks like writing '\0' as 1["3"] or 2["22"]".

Testing this in my c++ compiler shows that the expression is evaluated exactly as he stated, with no compile errors or warnings. Also, changing some of the digits in the expression caused it to evaluate to something else.
The following program:
Code:

#include <iostream>
using namespace std;
int main()
{
if (1["3"] == '\0')
cout << "1[\"3\"] == '\\0'\n";
if (2["22"] == '\0')
cout << "2[\"22\"] == '\\0'\n";
if (1["22"] == '\0')
cout << "1[\"22\"] == '\\0'\n";
if (2["3"] == '\0')
cout << "2[\"3\"] == '\\0'\n";
system("pause");
return 0;
}

gives the following output:
Code:

1["3"] == '\0'
2["22"] == '\0'
Press any key to continue . . .

I don't have any particular desire to obfuscate my code, but I would like to understand the syntax used here. What does the number before the brackets mean to the compiler? What does a string in brackets following it mean to the compiler?

In short, can anyone explain to me how 2["22"] evaluates to '\0' (and 1["22"] does not)?

Dan
• 09-10-2009
sigfriedmcwild
The trick here is that in c/c++ p[n] == n[p] (for arrays only of course)

Basically p[n] returns *(p + n) since arrays are pointers, but + is commutative so it doesn't matter if which way round the index and the pointer go (and the type checking allows it).

So in the 2["22"] case you have a const char* which is the string literal and you are indexing the last element of it which is always '\0' (remember string literals get null terminated automatically)
• 09-10-2009
dandeibler
Quote:

Originally Posted by sigfriedmcwild
The trick here is that in c/c++ p[n] == n[p] (for arrays only of course)

Basically p[n] returns *(p + n) since arrays are pointers, but + is commutative so it doesn't matter if which way round the index and the pointer go (and the type checking allows it).

So in the 2["22"] case you have a const char* which is the string literal and you are indexing the last element of it which is always '\0' (remember string literals get null terminated automatically)

I suppose if I'd actually bothered to output what the two additional statements in my test code evaluated to, I would have figured that out. :p
I never knew the language allowed you to do that (the reversal from the "normal" syntax). Thank you for the explanation! :)