簡體   English   中英

不能用 gcc-7 編譯

[英]Can't compile with gcc-7

我正在嘗試在 MacOS Catalina 上使用 GCC-7 編譯一些代碼。 GCC-7 是使用 homebrew 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

output 是:

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 的地方,它可以工作。 我認為 header 文件有問題。

將評論轉換為答案。

快速解決

#include <stdlib.h> > 之前添加#include <stdio.h> — 或幾乎任何其他標准header。 只有當<stdlib.h>是第一個系統 header 時,才會出現該錯誤。 我還沒弄清楚為什么。

在您的程序中,交換#include <math.h>#include <stdlib.h>行; 然后它將編譯(前提是您包含定義IDX的內容)。

背景

我在關於升級到 Catalina 10.15 后無法在 Mac 上編譯 C 程序的問答的評論中注意到了這一點——特別是評論12 格式化時,他們說:

一個奇怪的地方——我有一些代碼開始#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>中的標頭,代碼無法編譯; 使用相反順序的標頭,代碼編譯時不會出現任何問題。 <stdlib.h>有一些奇怪的地方。 像這樣的標准頭文件的順序不應該影響編譯,但是會。 這一切都很奇怪,因為本機 XCode 編譯器( /usr/bin/gcc/usr/bin/clang )不會遇到同樣的問題。

應用於問題中的代碼

將此應用於問題中的代碼,將#include <math.h>放在 #include #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>作為第一個包含 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 上編譯的自制 9.2.0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM