无法用 gcc-7 编译
Can't compile with gcc-7
我正在尝试在 MacOS Catalina 上使用 GCC-7 编译一些代码。
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 它有效。我认为头文件中有问题。
正在将评论转换为答案。
快速修复
在 #include <stdlib.h>
或几乎任何其他标准 header 之前添加 #include <stdio.h>
。仅当 <stdlib.h>
是第一个系统 header 时才会出现该错误。我还没弄明白为什么。
在您的程序中,交换 #include <math.h>
和 #include <stdlib.h>
行;然后它将编译(前提是您包含定义 IDX
的内容)。
背景
我在关于 Can't compile a C program on a Mac after upgrading to Catalina 10.15 — specifically comments 1 and 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 <stdlib.h>
之前添加 #include <ctype.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>
中的header,代码编译失败;使用相反顺序的 headers,代码编译时不会出现任何问题。 <stdlib.h>
有点奇怪。像这样的标准 header 的顺序 应该 不会影响编译,但是 会。 这一切有些奇怪,因为本机 XCode 编译器(/usr/bin/gcc
或 /usr/bin/clang
)不会 运行 遇到同样的问题。
应用于问题中的代码
将此应用于问题中的代码,将 #include <math.h>
放在 #include <stdlib.h>
之前可以避免问题中报告的错误。但是,该代码不可编译,因为未定义或声明 IDX
(并且这两个函数没有先前的原型,但并不是每个人都使用编译器选项来强制在之前声明 non-static 函数正在使用或定义)。
#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 多个 headers 的库目录时发现了问题;他们中的大多数工作正常,但是没有编译的 6 个左右有 <stdlib.h>
作为第一个包含 header.
编译器选项:
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 上编译的 home-built 9.2.0。
我正在尝试在 MacOS Catalina 上使用 GCC-7 编译一些代码。
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 它有效。我认为头文件中有问题。
正在将评论转换为答案。
快速修复
在 #include <stdlib.h>
或几乎任何其他标准 header 之前添加 #include <stdio.h>
。仅当 <stdlib.h>
是第一个系统 header 时才会出现该错误。我还没弄明白为什么。
在您的程序中,交换 #include <math.h>
和 #include <stdlib.h>
行;然后它将编译(前提是您包含定义 IDX
的内容)。
背景
我在关于 Can't compile a C program on a Mac after upgrading to Catalina 10.15 — specifically comments 1 and 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 <stdlib.h>
之前添加 #include <ctype.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>
中的header,代码编译失败;使用相反顺序的 headers,代码编译时不会出现任何问题。 <stdlib.h>
有点奇怪。像这样的标准 header 的顺序 应该 不会影响编译,但是 会。 这一切有些奇怪,因为本机 XCode 编译器(/usr/bin/gcc
或 /usr/bin/clang
)不会 运行 遇到同样的问题。
应用于问题中的代码
将此应用于问题中的代码,将 #include <math.h>
放在 #include <stdlib.h>
之前可以避免问题中报告的错误。但是,该代码不可编译,因为未定义或声明 IDX
(并且这两个函数没有先前的原型,但并不是每个人都使用编译器选项来强制在之前声明 non-static 函数正在使用或定义)。
#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 多个 headers 的库目录时发现了问题;他们中的大多数工作正常,但是没有编译的 6 个左右有 <stdlib.h>
作为第一个包含 header.
编译器选项:
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 上编译的 home-built 9.2.0。