From: bill@twwells.com (T. William Wells)
Newsgroups: comp.std.c
Subject: Re: Standard conformance and GCC 2.3.3
Date: 30 Dec 92 19:48:02 GMT
Organization: None, Mt. Laurel, NJ

In article <1992Dec30.011211.11409@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
: -----------------------------------------------------------------------------
: #1)  GCC fails to detect the error in the following code, even when the
:      -pedantic-errors option is used.
:
: void foo ()
: {
:   extern void bar (int i, ...);
:
:   bar (99, 88, 77);
: }
:
: void bar (int i, int j, int k) { }      /* ERROR */

Yes. All declarations of the same object or function must have
compatible types.

: -----------------------------------------------------------------------------
: #2)  GCC fails to detect the error in the following code, even when the
:      -pedantic-errors option is used.
:
: unsigned long overflow = LONG_MAX + 3; /* ERROR */

This is undefined and the compiler is not obligated to notice it.

: -----------------------------------------------------------------------------
: #3)  GCC incorrectly flags an error on the following standard-conformant code
:      when the -pedantic-errors option is in effect.
:
: typedef int T;
: void test_1 (int T) { }

The relevant statement: "An identifier declared as a typedef name
shall not be redeclared as a parameter". This is a correct
diagnostic.

: -----------------------------------------------------------------------------
: #4)  On x86 machines, GCC fails to properly implement explicit floating-point
:      casts of those floating-point expressions which get evaluated using the
:      (internal) 80-bit floating-point format.  This causes the following
:      program to yield a non-zero exit status.
:
: double point_four = 0.4;
: double point_one_six;
:
: int
: main ()
: {
:   point_one_six = (point_four * point_four);
:   if ((double)(point_four * point_four) != point_one_six)
:     {
:       return 1;
:     }
:   return 0;
: }

The compiler is allowed to use whatever extended precision it
wants for expressions. There is no requirement that this be
consistent between expressions. The first expression could, for
example, compute the results using pure double precision and the
second could use 80 bits for intermediate results, resulting in
the != being true. This is a quality of implementation issue.

: -----------------------------------------------------------------------------
: #5)  GCC incorrectly issues an error for the following standard-conformant
:      code.  (Note that `wchar_t' is the same as type `long int' on i486-svr4.)
:
: typedef long int wchar_t;
: wchar_t array5[4] = L"abcd";

Yes, the compiler should allow that.

: -----------------------------------------------------------------------------
: #6)  The following erroneous code causes GCC to crash with a signal 6.
:
: extern volatile struct s evs;
: void evs_test () { evs; }

Am I missing something? This code looks valid. It declares an
external struct that is volatile and then a function which
references that structure. Of course, that just makes it worse!

: -----------------------------------------------------------------------------
: #7)  When compiling an empty source file while the -pedantic-errors option
:      is in effect, GCC will generate an error message for a line number which
:      does not actually exist in the source file.  (The line number indicated
:      in the error message is equal to the number of lines actually in the
:      file plus one.)  Issuing error messages which reference non-existant
:      source lines may cause some related tools (e.g. emacs) to go bonkers.

But this isn't standard violating.

: -----------------------------------------------------------------------------
: #8)  GCC fails to issue errors for the following erroneous code, even when
:      the -pedantic-errors option is in effect.  (Note that the argument type
:      for the function is *not* a type which would result from integral
:      promotions.)
:
: void test_0 (char);
: void test_0 (c) char c; { }

Yes, there should be an error.

: -----------------------------------------------------------------------------
: #9)  GCC fails to issue errors in cases where a static function is referenced
:      but never defined, even when the -pedantic-errors option is used.
:
:      Example:
:
: static void s (); int main () { s (); return 1; }

Yes, there should be an error.

: -----------------------------------------------------------------------------
: #10)  GCC fails to issue an error for the following invalid C code, even when
:       the -pedantic-errors option is used.
:
: void (*func_ptr) ();
: int i;
: void test () { func_ptr = i ? 0 : 0; }         /* ERROR */

Yes, there should be an error.

: -----------------------------------------------------------------------------
: #11)  GCC fails to issue errors for the following invalid C code involving
:       comparison operators, even when the -pedantic-errors option is used.
:
: typedef int b_array[3];
: typedef int u_array[];
:
: typedef b_array *b_array_ptr;
: typedef u_array *u_array_ptr;
:
: b_array b_array_src;
: extern u_array u_array_src;
: int *ip;
: int i;
: b_array_ptr b_array_dest;
: u_array_ptr u_array_dest;
:
: void test_relational_operators ()
: {
:   i = & u_array_src > & b_array_src;            /* ERROR */
:   i = & b_array_src > & u_array_src;            /* ERROR */
:
:   i = & u_array_src <= & b_array_src;           /* ERROR */
:   i = & b_array_src <= & u_array_src;           /* ERROR */
:
:   i = u_array_dest > b_array_dest;              /* ERROR */
:   i = b_array_dest > u_array_dest;              /* ERROR */
:
:   i = u_array_dest <= b_array_dest;             /* ERROR */
:   i = b_array_dest <= u_array_dest;             /* ERROR */
: }

Yes, these all should fail because one of the operands is a
pointer to a complete type and the other is a pointer to an
incomplete type.

: -----------------------------------------------------------------------------
: #12)  GCC fails to issue errors for the following invalid C code involving
:       the binary `-' operator, even when the -pedantic-errors option is used.
:
: typedef int b_array[3];
: typedef int u_array[];
:
: typedef b_array *b_array_ptr;
: typedef u_array *u_array_ptr;
:
: b_array b_array_src;
: extern u_array u_array_src;
: int *ip;
: int i;
: b_array_ptr b_array_dest;
: u_array_ptr u_array_dest;
:
: void test_pointer_subtraction ()
: {
:   i = & u_array_src - & b_array_src;            /* ERROR */
:   i = & b_array_src - & u_array_src;            /* ERROR */
:
:   i = u_array_dest - b_array_dest;              /* ERROR */
:   i = b_array_dest - u_array_dest;              /* ERROR */
: }

These are not errors. Unlike comparison, subtract only requires
compatibility between the unqualified pointed to types.

: -----------------------------------------------------------------------------
: #13)  GCC fails to issue errors for the following invalid C code involving
:       invalid null pointer constants, even when the -pedantic-errors option
:       is used.  (GCC also fails to properly flag these kinds of invalid
:       null pointer constants in other contexts as well.)
:
: int (*fp) ();
: void test () { fp = (void *) (void *) 0; }    /* ERROR */

Right. This is an attempt to assign a null pointer of object type
rather than a null pointer constant to the function pointer.

: -----------------------------------------------------------------------------
: #14)  GCC fails to issue errors for the following invalid C code involving
:       invalid pointer type conversions, even when the -pedantic-errors option
:       is used.
:
: struct incomp1; /* never completed */
: struct incomp2; /* completed towards the end - may make a difference */
:
: typedef int             *p_to_object_type;
: typedef struct incomp1  *p_to_incomp1_type;
: typedef struct incomp2  *p_to_incomp2_type;
: typedef int             (*p_to_func_type) ();
:
: p_to_object_type        p_to_object_value;
: p_to_incomp1_type       p_to_incomp1_value;
: p_to_incomp2_type       p_to_incomp2_value;
: p_to_func_type          p_to_func_value;
:
: void
: test ()
: {
:   p_to_func_value = (p_to_func_type) p_to_object_value;         /* ERROR */
:   p_to_func_value = (p_to_func_type) p_to_incomp1_value;        /* ERROR */
:   p_to_func_value = (p_to_func_type) p_to_incomp2_value;        /* ERROR */
: }

No, that's not an error. I thought so at first; however, a careful
reading of the standard shows that these are undefined behavior,
not illegal behavior.

: -----------------------------------------------------------------------------
: #15)  GCC fails to issue errors for the following invalid C code involving
:       invalid pointer type conversions, even when the -pedantic-errors option
:       is used.
:
: struct incomp1; /* never completed */
: struct incomp2; /* completed towards the end - may make a difference */
:
: typedef int             *p_to_object_type;
: typedef struct incomp1  *p_to_incomp1_type;
: typedef struct incomp2  *p_to_incomp2_type;
: typedef int             (*p_to_func_type) ();
:
: p_to_object_type        p_to_object_value;
: p_to_incomp1_type       p_to_incomp1_value;
: p_to_incomp2_type       p_to_incomp2_value;
: p_to_func_type          p_to_func_value;
:
: void
: test ()
: {
:   p_to_object_value = (p_to_object_type) p_to_func_value;       /* ERROR */
:   p_to_incomp1_value = (p_to_incomp1_type) p_to_func_value;     /* ERROR */
:   p_to_incomp2_value = (p_to_incomp2_type) p_to_func_value;     /* ERROR */
: }

As above, this is not an error.

: -----------------------------------------------------------------------------
: #16)  GCC fails to issue errors for the following invalid C code involving
:       local redeclarations of objects, even when the -pedantic-errors option
:       is used.
:
: static int object_decl_6;
: static int object_defn_6 = 0;
:
: void
: test ()
: {
:     extern double object_decl_6;                /* ERROR */
:     extern double object_defn_6;                /* ERROR */
: }

This is undefined behavior; the compiler isn't required to issue
a diagnostic.

: -----------------------------------------------------------------------------
: #17)  GCC fails to issue errors for the following invalid C code involving
:       incompatible redeclarations, even when the -pedantic-errors option
:       is used.
:
: void callee (char c);
: void foobar () { void callee(); }     /* ERROR */
: void callee (char c) { }

Yes, that's an error.

: -----------------------------------------------------------------------------
: #18)  GCC incorrectly issues an error for the following standard-conformant
:       ANSI C code when the -pedantic-errors option is used.
:
: extern const int func_1 ();

Yes, that's acceptable code.

: -----------------------------------------------------------------------------
: #19)  GCC fails to issue an error for the following pair of incompatible
:       function declarations, even when the -pedantic-errors option is used.
:
: extern const int func_4 ();
: extern int func_4 ();                   /* ERROR */

Yes, that's an error.

: -----------------------------------------------------------------------------
: #20)  GCC incorrectly issues errors for the following standard-conformant
:       ANSI C code when the -pedantic-errors option is used.
:
: static enum E1 { red, green, blue};
: static struct S1 { int member; };
: static union U2 { int member; };
:
: void foobar ()
: {
:       auto enum E2 { red, green, blue };
:       auto struct S2 { int member; };
:       auto union U2 { int member; };
: }

Yes, those are all valid code.

---
Bill                            { rutgers | decwrl | telesci }!twwells!bill
bill@twwells.com
Newsgroups: comp.std.c