summaryrefslogtreecommitdiff
path: root/devdocs/gcc~13/incompatibilities.html
blob: d347210a57009d0b1958099fe6248a377ca17da9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<div class="section-level-extent" id="Incompatibilities"> <div class="nav-panel"> <p> Next: <a href="fixed-headers" accesskey="n" rel="next">Fixed Header Files</a>, Previous: <a href="interoperation" accesskey="p" rel="prev">Interoperation</a>, Up: <a href="trouble" accesskey="u" rel="up">Known Causes of Trouble with GCC</a> [<a href="index#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="indices" title="Index" rel="index">Index</a>]</p> </div>  <h1 class="section" id="Incompatibilities-of-GCC"><span>14.3 Incompatibilities of GCC<a class="copiable-link" href="#Incompatibilities-of-GCC"> ¶</a></span></h1>   <p>There are several noteworthy incompatibilities between GNU C and K&amp;R (non-ISO) versions of C. </p> <ul class="itemize mark-bullet"> <li>
   GCC normally makes string constants read-only. If several identical-looking string constants are used, GCC stores only one copy of the string.  <p>One consequence is that you cannot call <code class="code">mktemp</code> with a string constant argument. The function <code class="code">mktemp</code> always alters the string its argument points to. </p>    <p>Another consequence is that <code class="code">sscanf</code> does not work on some very old systems when passed a string constant as its format control string or input. This is because <code class="code">sscanf</code> incorrectly tries to write into the string constant. Likewise <code class="code">fscanf</code> and <code class="code">scanf</code>. </p> <p>The solution to these problems is to change the program to use <code class="code">char</code>-array variables with initialization strings for these purposes instead of string constants. </p> </li>
<li>
<code class="code">-2147483648</code> is positive. <p>This is because 2147483648 cannot fit in the type <code class="code">int</code>, so (following the ISO C rules) its data type is <code class="code">unsigned long int</code>. Negating this value yields 2147483648 again. </p> </li>
<li>GCC does not substitute macro arguments when they appear inside of string constants. For example, the following macro in GCC <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">#define foo(a) "a"</pre>
</div> <p>will produce output <code class="code">"a"</code> regardless of what the argument <var class="var">a</var> is. </p> </li>
<li>
  When you use <code class="code">setjmp</code> and <code class="code">longjmp</code>, the only automatic variables guaranteed to remain valid are those declared <code class="code">volatile</code>. This is a consequence of automatic register allocation. Consider this function: <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">jmp_buf j;

foo ()
{
  int a, b;

  a = fun1 ();
  if (setjmp (j))
    return a;

  a = fun2 ();
  /* <span class="r"><code class="code">longjmp (j)</code> may occur in <code class="code">fun3</code>.</span> */
  return a + fun3 ();
}</pre>
</div> <p>Here <code class="code">a</code> may or may not be restored to its first value when the <code class="code">longjmp</code> occurs. If <code class="code">a</code> is allocated in a register, then its first value is restored; otherwise, it keeps the last value stored in it. </p>  <p>If you use the <samp class="option">-W</samp> option with the <samp class="option">-O</samp> option, you will get a warning when GCC thinks such a problem might be possible. </p> </li>
<li>Programs that use preprocessing directives in the middle of macro arguments do not work with GCC. For example, a program like this will not work: <div class="example smallexample"> <div class="group"><pre class="example-preformatted" data-language="cpp">foobar (
#define luser
        hack)</pre></div>
</div> <p>ISO C does not permit such a construct. </p> </li>
<li>K&amp;R compilers allow comments to cross over an inclusion boundary (i.e. started in an include file and ended in the including file). </li>
<li>
   Declarations of external variables and functions within a block apply only to the block containing the declaration. In other words, they have the same scope as any other declaration in the same place. <p>In some other C compilers, an <code class="code">extern</code> declaration affects all the rest of the file even if it happens within a block. </p> </li>
<li>In traditional C, you can combine <code class="code">long</code>, etc., with a typedef name, as shown here: <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">typedef int foo;
typedef long foo bar;</pre>
</div> <p>In ISO C, this is not allowed: <code class="code">long</code> and other type modifiers require an explicit <code class="code">int</code>. </p> </li>
<li>
 PCC allows typedef names to be used as function parameters. </li>
<li>Traditional C allows the following erroneous pair of declarations to appear together in a given scope: <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">typedef int foo;
typedef foo foo;</pre>
</div> </li>
<li>GCC treats all characters of identifiers as significant. According to K&amp;R-1 (2.2), “No more than the first eight characters are significant, although more may be used.”. Also according to K&amp;R-1 (2.2), “An identifier is a sequence of letters and digits; the first character must be a letter. The underscore _ counts as a letter.”, but GCC also allows dollar signs in identifiers. </li>
<li>
 PCC allows whitespace in the middle of compound assignment operators such as ‘<samp class="samp">+=</samp>’. GCC, following the ISO standard, does not allow this. </li>
<li>
  GCC complains about unterminated character constants inside of preprocessing conditionals that fail. Some programs have English comments enclosed in conditionals that are guaranteed to fail; if these comments contain apostrophes, GCC will probably report an error. For example, this code would produce an error: <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">#if 0
You can't expect this to work.
#endif</pre>
</div> <p>The best solution to such a problem is to put the text into an actual C comment delimited by ‘<samp class="samp">/*…*/</samp>’. </p> </li>
<li>Many user programs contain the declaration ‘<samp class="samp">long time ();</samp>’. In the past, the system header files on many systems did not actually declare <code class="code">time</code>, so it did not matter what type your program declared it to return. But in systems with ISO C headers, <code class="code">time</code> is declared to return <code class="code">time_t</code>, and if that is not the same as <code class="code">long</code>, then ‘<samp class="samp">long time ();</samp>’ is erroneous. <p>The solution is to change your program to use appropriate system headers (<code class="code">&lt;time.h&gt;</code> on systems with ISO C headers) and not to declare <code class="code">time</code> if the system header files declare it, or failing that to use <code class="code">time_t</code> as the return type of <code class="code">time</code>. </p> </li>
<li>
 When compiling functions that return <code class="code">float</code>, PCC converts it to a double. GCC actually returns a <code class="code">float</code>. If you are concerned with PCC compatibility, you should declare your functions to return <code class="code">double</code>; you might as well say what you mean. </li>
<li>
  When compiling functions that return structures or unions, GCC output code normally uses a method different from that used on most versions of Unix. As a result, code compiled with GCC cannot call a structure-returning function compiled with PCC, and vice versa. <p>The method used by GCC is as follows: a structure or union which is 1, 2, 4 or 8 bytes long is returned like a scalar. A structure or union with any other size is stored into an address supplied by the caller (usually in a special, fixed register, but on some machines it is passed on the stack). The target hook <code class="code">TARGET_STRUCT_VALUE_RTX</code> tells GCC where to pass this address. </p> <p>By contrast, PCC on most target machines returns structures and unions of any size by copying the data into an area of static storage, and then returning the address of that storage as if it were a pointer value. The caller must copy the data from that memory area to the place where the value is wanted. GCC does not use this method because it is slower and nonreentrant. </p> <p>On some newer machines, PCC uses a reentrant convention for all structure and union returning. GCC on most of these machines uses a compatible convention when returning structures and unions in memory, but still returns small structures and unions in registers. </p>  <p>You can tell GCC to use a compatible convention for all structure and union returning with the option <samp class="option">-fpcc-struct-return</samp>. </p> </li>
<li>
  GCC complains about program fragments such as ‘<samp class="samp">0x74ae-0x4000</samp>’ which appear to be two hexadecimal constants separated by the minus operator. Actually, this string is a single <em class="dfn">preprocessing token</em>. Each such token must correspond to one token in C. Since this does not, GCC prints an error message. Although it may appear obvious that what is meant is an operator and two values, the ISO C standard specifically requires that this be treated as erroneous. <p>A <em class="dfn">preprocessing token</em> is a <em class="dfn">preprocessing number</em> if it begins with a digit and is followed by letters, underscores, digits, periods and ‘<samp class="samp">e+</samp>’, ‘<samp class="samp">e-</samp>’, ‘<samp class="samp">E+</samp>’, ‘<samp class="samp">E-</samp>’, ‘<samp class="samp">p+</samp>’, ‘<samp class="samp">p-</samp>’, ‘<samp class="samp">P+</samp>’, or ‘<samp class="samp">P-</samp>’ character sequences. (In strict C90 mode, the sequences ‘<samp class="samp">p+</samp>’, ‘<samp class="samp">p-</samp>’, ‘<samp class="samp">P+</samp>’ and ‘<samp class="samp">P-</samp>’ cannot appear in preprocessing numbers.) </p> <p>To make the above program fragment valid, place whitespace in front of the minus sign. This whitespace will end the preprocessing number. </p>
</li>
</ul> </div>  <div class="nav-panel"> <p> Next: <a href="fixed-headers">Fixed Header Files</a>, Previous: <a href="interoperation">Interoperation</a>, Up: <a href="trouble">Known Causes of Trouble with GCC</a> [<a href="index#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="indices" title="Index" rel="index">Index</a>]</p> </div><div class="_attribution">
  <p class="_attribution-p">
    &copy; Free Software Foundation<br>Licensed under the GNU Free Documentation License, Version 1.3.<br>
    <a href="https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Incompatibilities.html" class="_attribution-link">https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Incompatibilities.html</a>
  </p>
</div>