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