我正在尝试在MacOS Catalina上使用GCC-7编译一些代码。
使用自制软件brew install gcc@7
代码如下:
#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;
}
我正在使用gcc-7 -Iinc/ -o lib/test.o -c src/test.c
,输出为:
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
}
^
在不包含stdlib.h的地方,它起作用。我认为头文件中有问题。
答案 0 :(得分:2)
将评论转换为答案。
在#include <stdio.h>
之前添加#include <stdlib.h>
-或几乎任何其他标准标题。仅当<stdlib.h>
是第一个系统标头时,才会出现该错误。我还不知道为什么。
在程序中,交换#include <math.h>
和#include <stdlib.h>
行;然后将进行编译(前提是您提供了定义IDX
的内容)。
我在对Can't compile a C program on a Mac after upgrading to Catalina 10.15的问答中的评论中注意到了这一点,特别是评论1和2。格式化后,他们会说:
一个奇怪的地方-我有一些代码始于#include <stdlib.h>
,然后因编译失败而抱怨:
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);
但是,当我在#include <ctype.h>
之前添加#include <stdlib.h>
时,它将编译确定。我仍在研究这意味着什么以及如何自动处理它。 …
元素是路径名:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/
使用该问题的可接受答案,设置了环境变量CPATH
:
export CPATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
与此相关的另一个(接近最小)变体是:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return EXIT_SUCCESS;
}
如果标头的顺序为<stdlib.h>
,然后依次为<stdio.h>
,则代码将无法编译;如果标题相反,则代码编译时不会浪费时间。 <stdlib.h>
有点奇怪。像这样的标准标头的顺序应该不影响编译,但是会影响。一切都有些奇怪,因为本机XCode编译器(/usr/bin/gcc
或/usr/bin/clang
)不会遇到相同的问题。
将其应用于问题中的代码,将#include <math.h>
放在#include <stdlib.h>
之前可以避免问题中报告的错误。但是,该代码不可编译,因为未定义或声明IDX
(并且两个函数都没有先前的原型,但是并非每个人都使用编译器选项来强制使用非静态函数在使用前声明或定义)。
#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;
}
但是,如上所述,我还没有完全确定问题的根源,只是问题完全与问题中所述的一样(文件名,行号以及所有),并且存在简单但不明显的解决方法。我发现在编译包含大约200个源文件和100多个头的库目录时遇到的问题;它们中的大多数都能正常工作,但是未编译的6个左右版本将<stdlib.h>
作为第一个包含的标头。
编译器选项:
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是在macOS 10.14 Mojave上编译的自制9.2.0。