]>
Commit | Line | Data |
---|---|---|
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 | ||
10 | Incompatibilities of GCC | |
11 | ************************ | |
12 | ||
13 | There 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. |