Не могу скомпилировать с gcc-7

Я пытаюсь скомпилировать код с GCC-7 на MacOS Catalina. 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

и вывод:

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, он работает. Я думаю, что с заголовочными файлами что-то не так.


person sted    schedule 08.11.2019    source источник
comment
Как вы называете код? В случае, если отсутствие включения необходимого файла заголовка решает проблему, проблема, безусловно, связана с ошибкой в ​​вашем коде.   -  person Lundin    schedule 08.11.2019
comment
@Lundin Это не решает проблему, выдает эти предупреждения src/test.c:15:19: warning: implicit declaration of function 'malloc' [-Wimplicit-function-declaration]   -  person sted    schedule 08.11.2019
comment
Добавьте #include <stdio.h> перед #include <stdlib.h> - или почти любым другим стандартным заголовком. Вы получите эту ошибку, только если <stdlib.h> является первым системным заголовком. Я не понял почему. Я отметил это в комментарии к Q&A о невозможности компилировать программы на C на Catalina.   -  person Jonathan Leffler    schedule 08.11.2019
comment
@JonathanLeffler заслуживает ответа, если не в другом месте.   -  person Antti Haapala    schedule 08.11.2019
comment
Не работает с gcc 7,4.0 / Mint-19   -  person dash-o    schedule 08.11.2019
comment
Добро пожаловать в Stack Overflow. Обратите внимание, что предпочтительный способ сказать здесь `` спасибо '' - проголосовать за хорошие вопросы и полезные ответы (если у вас достаточно репутации для этого) и принять наиболее полезный ответ на любой вопрос, который вы задаете (что также дает вы немного повысите свою репутацию). См. Страницу О программе, а также Как здесь можно задать вопросы? и Что мне делать, когда кто-то ответит на мой вопрос?   -  person Jonathan Leffler    schedule 11.11.2019


Ответы (1)


Преобразование комментария в ответ.

Быстрая починка

Добавьте #include <stdio.h> перед #include <stdlib.h> - или почти любым другим стандартным заголовком. Вы получите эту ошибку, только если <stdlib.h> является первым системным заголовком. Я не понял почему.

В вашей программе поменяйте местами строки #include <math.h> и #include <stdlib.h>; затем он будет скомпилирован (при условии, что вы включите что-то, что определяет IDX).

Фон

Я отметил это в комментариях к Q&A о Невозможно скомпилировать программу C на Mac после обновления до 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#include <stdlib.h>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 - это самодельная версия 9.2.0, скомпилированная на macOS 10.14 Mojave.

person Jonathan Leffler    schedule 08.11.2019