This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Peculiar handling of -fsigned-char options in gcc 2.95.2


I've noticed an inconsistency in gcc's handling of conflicting
-fsigned-char and -funsigned-char options.  If both are given
on the command line, you'd expect the last one to win, no?
Well, it turns out they both win, in the sense that the compiler's
behavior is not self-consistent: the builtin #define __CHAR_UNSIGNED__ 
fails to match the actual codegen behavior.

Test case:

$ cat fs.c
#include <stdio.h>

int main()
{
#ifdef __CHAR_UNSIGNED__
  printf("__CHAR_UNSIGNED__ is defined\n");
#endif
#ifdef __CHAR_SIGNED__
  printf("__CHAR_SIGNED__ is defined\n");
#endif
  if ((int) (char) (-1) == -1)
    printf("char appears to be signed\n");
  if ((int) (char) (-1) == 255)
    printf("char appears to be unsigned\n");
  return 0;
}

On a machine where char is signed by default, I get:

$ gcc -v
Reading specs from /usr/local/lib/gcc-lib/hppa2.0-hp-hpux10.20/2.95.2/specs
gcc version 2.95.2 19991024 (release)
$ gcc fs.c ; ./a.out
char appears to be signed
$ gcc -fsigned-char fs.c ; ./a.out
char appears to be signed
$ gcc -funsigned-char fs.c ; ./a.out
__CHAR_UNSIGNED__ is defined
char appears to be unsigned
// OK so far, but here comes the killer:
$ gcc -funsigned-char -fsigned-char fs.c ; ./a.out
__CHAR_UNSIGNED__ is defined
char appears to be signed

Oops.  I surmise that -D__CHAR_UNSIGNED__ is executed instantly upon
seeing -funsigned-char in the options, whereas codegen depends on the
last setting of the option.

On a machine where char is unsigned by default, I get:

[tgl@g3 tmp]$ gcc -v
Reading specs from /usr/lib/gcc-lib/ppc-redhat-linux/2.95.2/specs
gcc version 2.95.2 19991024 (release/franzo)
[tgl@g3 tmp]$ gcc fs.c ; ./a.out
__CHAR_UNSIGNED__ is defined
char appears to be unsigned
[tgl@g3 tmp]$ gcc -fsigned-char fs.c ; ./a.out
char appears to be signed
[tgl@g3 tmp]$ gcc -funsigned-char fs.c ; ./a.out
__CHAR_UNSIGNED__ is defined
char appears to be unsigned
[tgl@g3 tmp]$ gcc -funsigned-char -fsigned-char fs.c ; ./a.out
char appears to be signed
[tgl@g3 tmp]$ gcc -fsigned-char -funsigned-char fs.c ; ./a.out
char appears to be unsigned
// uh-oh, where's the #define?

Here, it seems that -U__CHAR_UNSIGNED__ is executed instantly on
seeing -fsigned-char, but codegen takes the last setting.

This could be fixed either by establishing the correct state of the
#define only once after option scanning, or by having -funsigned-char
and -fsigned-char define or undefine the symbol always, regardless
of the default for the platform.

I haven't looked at the code, but I wonder whether there are not
similar inconsistencies in handling of other flags.

I spent a whole day tracking down "impossible" code misbehavior that
traced to this bug, so I hope you will fix it sometime, even though
it's surely a low-priority corner case.

			regards, tom lane

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]