]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/doc/gcc/known-causes-of-trouble-with-gcc/incompatibilities-of-gcc.rst
sphinx: add missing trailing newline
[thirdparty/gcc.git] / gcc / doc / gcc / known-causes-of-trouble-with-gcc / incompatibilities-of-gcc.rst
CommitLineData
c63539ff
ML
1..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6.. index:: incompatibilities of GCC, traditional
7
8.. _incompatibilities:
9
10Incompatibilities of GCC
11************************
12
13There are several noteworthy incompatibilities between GNU C and K&R
14(non-ISO) versions of C.
15
16.. index:: string constants, read-only strings, shared strings
17
18* GCC normally makes string constants read-only. If several
19 identical-looking string constants are used, GCC stores only one
20 copy of the string.
21
22 .. index:: mktemp, and constant strings
23
24 One consequence is that you cannot call ``mktemp`` with a string
25 constant argument. The function ``mktemp`` always alters the
26 string its argument points to.
27
28 .. index:: sscanf, and constant strings, fscanf, and constant strings, scanf, and constant strings
29
30 Another consequence is that ``sscanf`` does not work on some very
31 old systems when passed a string constant as its format control string
32 or input. This is because ``sscanf`` incorrectly tries to write
33 into the string constant. Likewise ``fscanf`` and ``scanf``.
34
35 The solution to these problems is to change the program to use
36 ``char`` -array variables with initialization strings for these
37 purposes instead of string constants.
38
39* ``-2147483648`` is positive.
40
41 This is because 2147483648 cannot fit in the type ``int``, so
42 (following the ISO C rules) its data type is ``unsigned long int``.
43 Negating this value yields 2147483648 again.
44
45* GCC does not substitute macro arguments when they appear inside of
46 string constants. For example, the following macro in GCC
47
48 .. code-block:: c++
49
50 #define foo(a) "a"
51
52 will produce output ``"a"`` regardless of what the argument :samp:`{a}` is.
53
54 .. index:: setjmp incompatibilities, longjmp incompatibilities
55
56* When you use ``setjmp`` and ``longjmp``, the only automatic
57 variables guaranteed to remain valid are those declared
58 ``volatile``. This is a consequence of automatic register
59 allocation. Consider this function:
60
61 .. code-block:: c++
62
63 jmp_buf j;
64
65 foo ()
66 {
67 int a, b;
68
69 a = fun1 ();
70 if (setjmp (j))
71 return a;
72
73 a = fun2 ();
74 /* longjmp (j) may occur in fun3. */
75 return a + fun3 ();
76 }
77
78 Here ``a`` may or may not be restored to its first value when the
79 ``longjmp`` occurs. If ``a`` is allocated in a register, then
80 its first value is restored; otherwise, it keeps the last value stored
81 in it.
82
83 .. index:: W
84
85 If you use the :option:`-W` option with the :option:`-O` option, you will
86 get a warning when GCC thinks such a problem might be possible.
87
88* Programs that use preprocessing directives in the middle of macro
89 arguments do not work with GCC. For example, a program like this
90 will not work:
91
92 .. code-block:: c++
93
94 foobar (
95 #define luser
96 hack)
97
98 ISO C does not permit such a construct.
99
100* K&R compilers allow comments to cross over an inclusion boundary
101 (i.e. started in an include file and ended in the including file).
102
103 .. index:: external declaration scope, scope of external declarations, declaration scope
104
105* Declarations of external variables and functions within a block apply
106 only to the block containing the declaration. In other words, they
107 have the same scope as any other declaration in the same place.
108
109 In some other C compilers, an ``extern`` declaration affects all the
110 rest of the file even if it happens within a block.
111
112* In traditional C, you can combine ``long``, etc., with a typedef name,
113 as shown here:
114
115 .. code-block:: c++
116
117 typedef int foo;
118 typedef long foo bar;
119
120 In ISO C, this is not allowed: ``long`` and other type modifiers
121 require an explicit ``int``.
122
123 .. index:: typedef names as function parameters
124
125* PCC allows typedef names to be used as function parameters.
126
127* Traditional C allows the following erroneous pair of declarations to
128 appear together in a given scope:
129
130 .. code-block:: c++
131
132 typedef int foo;
133 typedef foo foo;
134
135* GCC treats all characters of identifiers as significant. According to
136 K&R-1 (2.2), 'No more than the first eight characters are significant,
137 although more may be used.'. Also according to K&R-1 (2.2), 'An
138 identifier is a sequence of letters and digits; the first character must
139 be a letter. The underscore _ counts as a letter.', but GCC also
140 allows dollar signs in identifiers.
141
142 .. index:: whitespace
143
144* PCC allows whitespace in the middle of compound assignment operators
145 such as :samp:`+=`. GCC, following the ISO standard, does not
146 allow this.
147
148 .. index:: apostrophes, '
149
150* GCC complains about unterminated character constants inside of
151 preprocessing conditionals that fail. Some programs have English
152 comments enclosed in conditionals that are guaranteed to fail; if these
153 comments contain apostrophes, GCC will probably report an error. For
154 example, this code would produce an error:
155
156 .. code-block:: c++
157
158 #if 0
159 You can't expect this to work.
160 #endif
161
162 The best solution to such a problem is to put the text into an actual
163 C comment delimited by :samp:`/*...*/`.
164
165* Many user programs contain the declaration :samp:`long time ();`. In the
166 past, the system header files on many systems did not actually declare
167 ``time``, so it did not matter what type your program declared it to
168 return. But in systems with ISO C headers, ``time`` is declared to
169 return ``time_t``, and if that is not the same as ``long``, then
170 :samp:`long time ();` is erroneous.
171
172 The solution is to change your program to use appropriate system headers
173 (``<time.h>`` on systems with ISO C headers) and not to declare
174 ``time`` if the system header files declare it, or failing that to
175 use ``time_t`` as the return type of ``time``.
176
177 .. index:: float as function value type
178
179* When compiling functions that return ``float``, PCC converts it to
180 a double. GCC actually returns a ``float``. If you are concerned
181 with PCC compatibility, you should declare your functions to return
182 ``double`` ; you might as well say what you mean.
183
184 .. index:: structures, unions
185
186* When compiling functions that return structures or unions, GCC
187 output code normally uses a method different from that used on most
188 versions of Unix. As a result, code compiled with GCC cannot call
189 a structure-returning function compiled with PCC, and vice versa.
190
191 The method used by GCC is as follows: a structure or union which is
192 1, 2, 4 or 8 bytes long is returned like a scalar. A structure or union
193 with any other size is stored into an address supplied by the caller
194 (usually in a special, fixed register, but on some machines it is passed
195 on the stack). The target hook ``TARGET_STRUCT_VALUE_RTX``
196 tells GCC where to pass this address.
197
198 By contrast, PCC on most target machines returns structures and unions
199 of any size by copying the data into an area of static storage, and then
200 returning the address of that storage as if it were a pointer value.
201 The caller must copy the data from that memory area to the place where
202 the value is wanted. GCC does not use this method because it is
203 slower and nonreentrant.
204
205 On some newer machines, PCC uses a reentrant convention for all
206 structure and union returning. GCC on most of these machines uses a
207 compatible convention when returning structures and unions in memory,
208 but still returns small structures and unions in registers.
209
210 .. index:: fpcc-struct-return
211
212 You can tell GCC to use a compatible convention for all structure and
213 union returning with the option :option:`-fpcc-struct-return`.
214
215 .. index:: preprocessing tokens, preprocessing numbers
216
217* GCC complains about program fragments such as :samp:`0x74ae-0x4000`
218 which appear to be two hexadecimal constants separated by the minus
219 operator. Actually, this string is a single :dfn:`preprocessing token`.
220 Each such token must correspond to one token in C. Since this does not,
221 GCC prints an error message. Although it may appear obvious that what
222 is meant is an operator and two values, the ISO C standard specifically
223 requires that this be treated as erroneous.
224
225 A :dfn:`preprocessing token` is a :dfn:`preprocessing number` if it
226 begins with a digit and is followed by letters, underscores, digits,
227 periods and :samp:`e+`, :samp:`e-`, :samp:`E+`, :samp:`E-`, :samp:`p+`,
228 :samp:`p-`, :samp:`P+`, or :samp:`P-` character sequences. (In strict C90
229 mode, the sequences :samp:`p+`, :samp:`p-`, :samp:`P+` and :samp:`P-` cannot
230 appear in preprocessing numbers.)
231
232 To make the above program fragment valid, place whitespace in front of
3ed1b4ce 233 the minus sign. This whitespace will end the preprocessing number.