gcc: Incompatibilities

1 
1 13.3 Incompatibilities of GCC
1 =============================
1 
1 There are several noteworthy incompatibilities between GNU C and K&R
1 (non-ISO) versions of C.
1 
1    * GCC normally makes string constants read-only.  If several
1      identical-looking string constants are used, GCC stores only one
1      copy of the string.
1 
1      One consequence is that you cannot call 'mktemp' with a string
1      constant argument.  The function 'mktemp' always alters the string
1      its argument points to.
1 
1      Another consequence is that 'sscanf' does not work on some very old
1      systems when passed a string constant as its format control string
1      or input.  This is because 'sscanf' incorrectly tries to write into
1      the string constant.  Likewise 'fscanf' and 'scanf'.
1 
1      The solution to these problems is to change the program to use
1      'char'-array variables with initialization strings for these
1      purposes instead of string constants.
1 
1    * '-2147483648' is positive.
1 
1      This is because 2147483648 cannot fit in the type 'int', so
1      (following the ISO C rules) its data type is 'unsigned long int'.
1      Negating this value yields 2147483648 again.
1 
1    * GCC does not substitute macro arguments when they appear inside of
1      string constants.  For example, the following macro in GCC
1 
1           #define foo(a) "a"
1 
1      will produce output '"a"' regardless of what the argument A is.
1 
1    * When you use 'setjmp' and 'longjmp', the only automatic variables
1      guaranteed to remain valid are those declared 'volatile'.  This is
1      a consequence of automatic register allocation.  Consider this
1      function:
1 
1           jmp_buf j;
1 
1           foo ()
1           {
1             int a, b;
1 
1             a = fun1 ();
1             if (setjmp (j))
1               return a;
1 
1             a = fun2 ();
1             /* 'longjmp (j)' may occur in 'fun3'. */
1             return a + fun3 ();
1           }
1 
1      Here 'a' may or may not be restored to its first value when the
1      'longjmp' occurs.  If 'a' is allocated in a register, then its
1      first value is restored; otherwise, it keeps the last value stored
1      in it.
1 
1      If you use the '-W' option with the '-O' option, you will get a
1      warning when GCC thinks such a problem might be possible.
1 
1    * Programs that use preprocessing directives in the middle of macro
1      arguments do not work with GCC.  For example, a program like this
1      will not work:
1 
1           foobar (
1           #define luser
1                   hack)
1 
1      ISO C does not permit such a construct.
1 
1    * K&R compilers allow comments to cross over an inclusion boundary
1      (i.e. started in an include file and ended in the including file).
1 
1    * Declarations of external variables and functions within a block
1      apply only to the block containing the declaration.  In other
1      words, they have the same scope as any other declaration in the
1      same place.
1 
1      In some other C compilers, an 'extern' declaration affects all the
1      rest of the file even if it happens within a block.
1 
1    * In traditional C, you can combine 'long', etc., with a typedef
1      name, as shown here:
1 
1           typedef int foo;
1           typedef long foo bar;
1 
1      In ISO C, this is not allowed: 'long' and other type modifiers
1      require an explicit 'int'.
1 
1    * PCC allows typedef names to be used as function parameters.
1 
1    * Traditional C allows the following erroneous pair of declarations
1      to appear together in a given scope:
1 
1           typedef int foo;
1           typedef foo foo;
1 
1    * GCC treats all characters of identifiers as significant.  According
1      to K&R-1 (2.2), "No more than the first eight characters are
1      significant, although more may be used.".  Also according to K&R-1
1      (2.2), "An identifier is a sequence of letters and digits; the
1      first character must be a letter.  The underscore _ counts as a
1      letter.", but GCC also allows dollar signs in identifiers.
1 
1    * PCC allows whitespace in the middle of compound assignment
1      operators such as '+='.  GCC, following the ISO standard, does not
1      allow this.
1 
1    * GCC complains about unterminated character constants inside of
1      preprocessing conditionals that fail.  Some programs have English
1      comments enclosed in conditionals that are guaranteed to fail; if
1      these comments contain apostrophes, GCC will probably report an
1      error.  For example, this code would produce an error:
1 
1           #if 0
1           You can't expect this to work.
1           #endif
1 
1      The best solution to such a problem is to put the text into an
1      actual C comment delimited by '/*...*/'.
1 
1    * Many user programs contain the declaration 'long time ();'.  In the
1      past, the system header files on many systems did not actually
1      declare 'time', so it did not matter what type your program
1      declared it to return.  But in systems with ISO C headers, 'time'
1      is declared to return 'time_t', and if that is not the same as
1      'long', then 'long time ();' is erroneous.
1 
1      The solution is to change your program to use appropriate system
1      headers ('<time.h>' on systems with ISO C headers) and not to
1      declare 'time' if the system header files declare it, or failing
1      that to use 'time_t' as the return type of 'time'.
1 
1    * When compiling functions that return 'float', PCC converts it to a
1      double.  GCC actually returns a 'float'.  If you are concerned with
1      PCC compatibility, you should declare your functions to return
1      'double'; you might as well say what you mean.
1 
1    * When compiling functions that return structures or unions, GCC
1      output code normally uses a method different from that used on most
1      versions of Unix.  As a result, code compiled with GCC cannot call
1      a structure-returning function compiled with PCC, and vice versa.
1 
1      The method used by GCC is as follows: a structure or union which is
1      1, 2, 4 or 8 bytes long is returned like a scalar.  A structure or
1      union with any other size is stored into an address supplied by the
1      caller (usually in a special, fixed register, but on some machines
1      it is passed on the stack).  The target hook
1      'TARGET_STRUCT_VALUE_RTX' tells GCC where to pass this address.
1 
1      By contrast, PCC on most target machines returns structures and
1      unions of any size by copying the data into an area of static
1      storage, and then returning the address of that storage as if it
1      were a pointer value.  The caller must copy the data from that
1      memory area to the place where the value is wanted.  GCC does not
1      use this method because it is slower and nonreentrant.
1 
1      On some newer machines, PCC uses a reentrant convention for all
1      structure and union returning.  GCC on most of these machines uses
1      a compatible convention when returning structures and unions in
1      memory, but still returns small structures and unions in registers.
1 
1      You can tell GCC to use a compatible convention for all structure
1      and union returning with the option '-fpcc-struct-return'.
1 
1    * GCC complains about program fragments such as '0x74ae-0x4000' which
1      appear to be two hexadecimal constants separated by the minus
1      operator.  Actually, this string is a single "preprocessing token".
1      Each such token must correspond to one token in C.  Since this does
1      not, GCC prints an error message.  Although it may appear obvious
1      that what is meant is an operator and two values, the ISO C
1      standard specifically requires that this be treated as erroneous.
1 
1      A "preprocessing token" is a "preprocessing number" if it begins
1      with a digit and is followed by letters, underscores, digits,
1      periods and 'e+', 'e-', 'E+', 'E-', 'p+', 'p-', 'P+', or 'P-'
1      character sequences.  (In strict C90 mode, the sequences 'p+',
1      'p-', 'P+' and 'P-' cannot appear in preprocessing numbers.)
1 
1      To make the above program fragment valid, place whitespace in front
1      of the minus sign.  This whitespace will end the preprocessing
1      number.
1