blog dds

2005.07.17

GCC Obfuscated Code

For years I've struggled to understand the GNU compiler collection internals, I am ashamed to say, without much success. I always thought that the subject was intrinsically too complicated for me, but after struggling to understand a two line gcc code snippet of a fairly simple operation for more than two minutes, I realized that the code style may have something to do with my problems.

Here is the relevant code:

#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
  ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
   || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
   || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
   || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \
   || (CHAR) == 'B' || (CHAR) == 'b')

/* [...] */
	  const char *p = argv[i] + 1;
	  int c = *p;
	  int nskip = 1;

	  if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
	    nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0);
Before reading on, I urge you to try to understand what the if code does.

Here is my understanding. The two elements of the if statements are Boolean expressions, and therefore take values 0 or 1. Therefore, the inequality will be true only when the first term is 1 and the second 0. This is the only case that will allow the execution of the next statement, so the result of the subtraction will always be 1. Thus, the if statement could (and, I believe, should) be written as:

	  if (SWITCH_TAKES_ARG (c) && (p[1] == 0))
	    nskip++;
Case closed.

Read and post comments, or share through   


Creative Commons License Last modified: Sunday, July 17, 2005 1:11 pm
Unless otherwise expressly stated, all original material on this page created by Diomidis Spinellis is licensed under a Creative Commons Attribution-Share Alike 3.0 Greece License.