无法用 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。