I am trying to compile some code with GCC-7 on MacOS Catalina.
The GCC-7 was installed using homebrew brew install gcc@7
The code is the following:
#include <stdlib.h>
#include <math.h>
double distance(double *a, double *b, int d) {
double dist = 0;
for(int i = 0; i < d; i++) {
dist += pow(a[i]-b[i],2);
}
return sqrt(dist);
}
double *computeDistances (double *X, int n, int d) {
double *dist = malloc( (n-1) * sizeof(double) );
double *vp = X + (n-1)*d;
for(int i = 0; i < n-1; i++) {
dist[i] = distance(&(X[IDX(d,i,0)]), vp, d);
}
return dist;
}
I'm compiling with gcc-7 -Iinc/ -o lib/test.o -c src/test.c
and the output is:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/wait.h:110:0,
from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h:66,
from src/test.c:1:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/resource.h: In function 'getiopolicy_np':
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/resource.h:443:34: error: expected declaration specifiers before '__OSX_AVAILABLE_STARTING'
int getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
^~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/resource.h:449:39: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__OSX_AVAILABLE_STARTING'
int setiopolicy_np(int, int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libkern/_OSByteOrder.h:66:0,
from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_endian.h:130,
from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/i386/endian.h:99,
from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/endian.h:35,
from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/wait.h:186,
from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h:66,
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/resource.h:443:1: error: parameter name omitted
src/test.c:21:1: error: expected '{' at end of input
}
^
Where I do not include stdlib.h it works. I think there's something wrong in the header files.
Converting a comment into an answer.
Add #include <stdio.h>
before #include <stdlib.h>
— or almost any other standard header. You get that error only if <stdlib.h>
is the first system header. I haven’t worked out why.
In your program, swap the #include <math.h>
and #include <stdlib.h>
lines; it will then compile (provided that you include something that defines IDX
).
I noted this in comments to the Q&A about Can't compile a C program on a Mac after upgrading to Catalina 10.15 — specifically comments 1 and 2. When formatted, they say:
One oddity — I've got some code which started #include <stdlib.h>
and then failed to compile complaining about:
In file included from …/usr/include/sys/wait.h:110,
from …/usr/include/stdlib.h:66,
from bm.c:27:
…/usr/include/sys/resource.h:443:9: error: no previous prototype for ‘getiopolicy_np’ [-Werror=missing-prototypes]
443 | int getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
Yet, when I add #include <ctype.h>
before #include <stdlib.h>
, it compiles OK. I'm still working out what this means and how to handle it automatically. The …
elements are the pathname:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/
Using the accepted answer to that question, the environment variable CPATH
was set:
export CPATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
Another (close to minimal) variant on this is:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return EXIT_SUCCESS;
}
With the headers in the sequence <stdlib.h>
then <stdio.h>
, the code fails to compile; with the headers in the reverse sequence, the code compiles with no wittering. There is something weird about <stdlib.h>
. The order of the standard headers like that should not affect the compilation, but does. There's something very odd about it all because the native XCode compilers (/usr/bin/gcc
or /usr/bin/clang
) do not run into the same problem.
Applying this to the code in the question, placing #include <math.h>
before #include <stdlib.h>
avoids the error(s) reported in the question. The code is not compilable, though, because IDX
is not defined or declared (and there aren't prior prototypes for the two functions, but not everyone uses compiler options to enforce that non-static functions are declared before being used or defined).
#include <math.h>
#include <stdlib.h>
// ...and a definition of IDX
// ...and maybe declarations of distance() and computeDistances()
double distance(double *a, double *b, int d)
{
double dist = 0;
for (int i = 0; i < d; i++)
dist += pow(a[i] - b[i], 2);
return sqrt(dist);
}
double *computeDistances(double *X, int n, int d)
{
double *dist = malloc((n-1) * sizeof(*dist));
double *vp = X + (n-1) * d;
for (int i = 0; i < n-1; i++)
dist[i] = distance(&(X[IDX(d, i, 0)]), vp, d);
return dist;
}
However, as I noted above, I've not fully established what the cause of the trouble is, only that there is trouble exactly as described in the question (file names and line numbers and all), and that there is a simple but not obvious workaround. I spotted the problem compiling a library directory with about 200 source files and just over 100 headers; most of them worked fine, but the 6 or so that didn't compile had <stdlib.h>
as the first included header.
Compiler options:
gcc -O3 -g -std=c11 -pedantic -Wall -Wextra -Werror -Wshadow -Wmissing-prototypes \
-Wpointer-arith -Wwrite-strings -Wold-style-definition -Wcast-qual -Wstrict-prototypes \
-o trial-1 trial-1.c
GCC is a home-built 9.2.0 compiled on macOS 10.14 Mojave.