You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Charlie Gordon <gm...@chqrlie.org> on 2004/06/28 15:53:38 UTC
bug in header files
Hi all,
I'm reporting this problem here, because apache.bugs seems flooded with
spam.
The way TRUE is defined in some apache headers files is incorrect :
modules/ssl/ssl_expr.h:35:#define TRUE !FALSE
apache/ap_ctx.h:70:#define TRUE !FALSE
apache/ap_hook.h:358:#define TRUE !FALSE
apache/ap_mm.h:70:#define TRUE !FALSE
missing parentheses may cause incorrect expression results, because of
operator precedence.
I agree that it is a remote possibility, because unary prefix operator have
a high precedence, but it is still possible, and as such should not stay in
published header files.
The program below illustrates this possibility :
#include <stdio.h>
int main(int argc, char **argv)
{
#undef TRUE
#undef FALSE
#define FALSE 0
#define TRUE 1
printf("#define FALSE 0\n#define TRUE 1\n");
printf("'N' = %d <-> FALSE[\"NY\"] = %d\n", 'N', FALSE["NY"]);
printf("'Y' = %d <-> TRUE[\"NY\"] = %d\n", 'Y', TRUE["NY"]);
#undef TRUE
#undef FALSE
#define FALSE 0
#define TRUE !FALSE
printf("#define FALSE 0\n#define TRUE !FALSE\n");
printf("'N' = %d <-> FALSE[\"NY\"] = %d\n", 'N', FALSE["NY"]);
printf("'Y' = %d <-> TRUE[\"NY\"] = %d\n", 'Y', TRUE["NY"]);
return 0;
}
output is :
#define FALSE 0
#define TRUE 1
'N' = 78 <-> FALSE["NY"] = 78
'Y' = 89 <-> TRUE["NY"] = 89
#define FALSE 0
#define TRUE !FALSE
'N' = 78 <-> FALSE["NY"] = 78
'Y' = 89 <-> TRUE["NY"] = 0
Just my 2 cents ;-)
Charlie Gordon.
The C teaser.
Re: bug in header files
Posted by Charlie Gordon <gm...@chqrlie.org>.
On Monday, Patrick W. thus responded:
Indeed.. Where does that construct come from?
> printf("'N' = %d <-> FALSE[\"NY\"] = %d\n", 'N', FALSE["NY"]);
I have never seend TRUE["NY"], and would have guessed cpp would change
it to 1["NY"] which doesn't mean anything to me. It appears to want to
be "NY"[1] ?! How come it works?
---------
I guess the example code requires some explaining:
In the first case, TRUE["NY"] expands to 1["NY"] which is semantically
interpreted as *(1 + "NY") and therefore computes to 'Y'.
Whereas in the second case, TRUE["NY"] expands to !FALSE["NY"] which in
turn expands to !0["NY"] .
That computes to !*(0 + "NY") simplified into !*"NY" or !'N' finally
resulting in the integer value 0.
Unbeknownst to the vast majority of C programmers, subscripting in C is
indeed commutative:
p[i] is the same as *(p + i) same as *(i + p) or i[p].
I've seen it used in obfuscated C code contest submissions, in C puzzles,
and similar teasing tests.
Enjoy,
Charlie Gordon,
The C teaser