【问题标题】:Can't compile with gcc-7不能用 gcc-7 编译
【发布时间】:2020-03-05 01:04:54
【问题描述】:

我正在尝试在 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 的地方它可以工作。我认为头文件有问题。

【问题讨论】:

  • 代码怎么调用?如果 not 包含必要的头文件可以解决问题,那么问题肯定是代码中的错误。
  • @Lundin 它没有解决问题,它给出了这些警告src/test.c:15:19: warning: implicit declaration of function 'malloc' [-Wimplicit-function-declaration]
  • #include &lt;stdlib.h&gt; 之前添加#include &lt;stdio.h&gt; — 或几乎任何其他标准标题。仅当 &lt;stdlib.h&gt; 是第一个系统标头时,您才会收到该错误。我还没弄清楚为什么。我在关于无法在 Catalina 上编译 C 程序的 Q&A 评论中注意到了这一点。
  • @JonathanLeffler 如果不是在其他地方值得回答。
  • 在 gcc 7,4.0 / Mint-19 中不会发生

标签: c macos gcc macos-catalina gcc7


【解决方案1】:

将评论转化为答案。

快速修复

#include &lt;stdlib.h&gt; 之前添加#include &lt;stdio.h&gt; — 或几乎任何其他标准标题。仅当 &lt;stdlib.h&gt; 是第一个系统标头时,您才会收到该错误。我还没弄清楚为什么。

在您的程序中,交换 #include &lt;math.h&gt;#include &lt;stdlib.h&gt; 行;然后它将编译(前提是您包含定义 IDX 的内容)。

背景

我在关于 Can't compile a C program on a Mac after upgrading to Catalina 10.15 的问答中提到了这一点,特别是 cmets 12。格式化后,他们会说:

有一个奇怪的地方——我有一些代码以 #include &lt;stdlib.h&gt; 开头,然后抱怨编译失败:

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 &lt;stdlib.h&gt; 之前添加#include &lt;ctype.h&gt; 时,它编译正常。我仍在研究这意味着什么以及如何自动处理它。 元素是路径名:

/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;
}

&lt;stdlib.h&gt;然后&lt;stdio.h&gt;序列中的标题,代码编译失败;使用相反顺序的标头,代码编译时不会出现任何问题。 &lt;stdlib.h&gt; 有点奇怪。像这样的标准头文件的顺序应该不会影响编译,但会。这一切都很奇怪,因为原生 XCode 编译器(/usr/bin/gcc 或 @987654343 @) 不要遇到同样的问题。

应用于问题中的代码

将此应用于问题中的代码,将#include &lt;math.h&gt; 放在#include &lt;stdlib.h&gt; 之前可以避免问题中报告的错误。但是,代码不可编译,因为 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 个左右将 &lt;stdlib.h&gt; 作为第一个包含的标头。

编译器选项:

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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多