Почему этот код компилируется с clang, но не с gcc? Я изучаю непрозрачные структуры в C

#c #gcc #clang

#c #gcc #clang

Вопрос:

Я изучаю непрозрачную структуру в C. У меня есть файл заголовка, в котором я ввел непрозрачную структуру и API. Затем я переношу реализацию в файл .c и создаю тестовый файл для приложения. Когда я пытаюсь скомпилировать его с помощью clang [Apple clang версии 11.0.3 (clang-1103.0.32.62)] это приложение и запустить его, оно работает так, как ожидалось, оно терпит неудачу, когда я использую gcc [gcc-10 (Homebrew GCC 10.2.0) 10.2.0].

Я перечисляю исходный код ниже.

counter.h

 #ifndef MY_COUNTER_H
#define MY_COUNTER_H
typedef struct counter Counter;

/* Prototypes */
Counter *counterCreate(void);
void counterDestroy(Counter *c);
int counterIncrement(Counter *c);

#endif
  

counter.c

 #include<stdlib.h>
#include<stdio.h>
#include<assert.h>

#include "counter.h"

struct counter {
    int value;
};

/* Create a counter */
Counter *counterCreate(void)
{
    Counter *c;
    c = (Counter *)malloc(sizeof(Counter));
    assert(c);
    c->value = 0;
    return c;
}

/* Release memory slot owned by counter */
void counterDestroy(Counter *c)
{
    free(c);
}

/* Increment the current value in counter and return it */
int counterIncrement(Counter *c)
{
    return   (c->value);
}
  

tstCounter.c

 #include<stdio.h>

#include "counter.h"

int main(void)
{
    Counter *c;
    c = counterCreate();
    int value;
    while((value=counterIncrement(c)) < 10){
        printf("%d ", value);
    }
    putchar('n');
    counterDestroy(c);
    return 0;
}
  

Вот как код был скомпилирован с помощью clang:

 clang -Wall -Wextra -c counter.c
clang -Wall -Wextra -c tstCounter.c
clang counter.o tstCounter.o -o counterEXE

#
# Then the execution proceed as follows:
./counterEXE
# which produce the following output:
1 2 3 4 5 6 7 8 9 
  

Но тот же процесс не удался с gcc

 gcc -Wall -Wextra -c counter.c
  

которые выдают следующий результат:

 In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/wait.h:110,
                 from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:66,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/resource.h: In function 'getiopolicy_np':
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/resource.h:447:34: error: expected declaration specifiers before '__OSX_AVAILABLE_STARTING'
  447 | int     getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/resource.h:453:39: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__OSX_AVAILABLE_STARTING'
  453 | int     setiopolicy_np(int, int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
      |                                       ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/libkern/_OSByteOrder.h:66,
                 from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_endian.h:130,
                 from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/i386/endian.h:99,
                 from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/machine/endian.h:35,
                 from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/wait.h:186,
                 from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:66,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/libkern/i386/_OSByteOrder.h:49:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
   49 | {
      | ^
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/libkern/i386/_OSByteOrder.h:58:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
   58 | {
      | ^
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/libkern/i386/_OSByteOrder.h:96:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
   96 | {
      | ^
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:77,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types/_ct_rune_t.h:32:28: error: storage class specified for parameter 'ct_rune_t'
   32 | typedef __darwin_ct_rune_t ct_rune_t;
      |                            ^~~~~~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:78,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types/_rune_t.h:31:25: error: storage class specified for parameter 'rune_t'
   31 | typedef __darwin_rune_t rune_t;
      |                         ^~~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:81,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types/_wchar_t.h:34:26: error: storage class specified for parameter 'wchar_t'
   34 | typedef __darwin_wchar_t wchar_t;
      |                          ^~~~~~~
In file included from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:86:3: error: storage class specified for parameter 'div_t'
   86 | } div_t;
      |   ^~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:91:3: error: storage class specified for parameter 'ldiv_t'
   91 | } ldiv_t;
      |   ^~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:97:3: error: storage class specified for parameter 'lldiv_t'
   97 | } lldiv_t;
      |   ^~~~~~~
In file included from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:118:12: error: sto
rage class specified for parameter '__mb_cur_max'
  118 | extern int __mb_cur_max;
      |            ^~~~~~~~~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:128,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/malloc/_malloc.h:52:74: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__OSX_AVAILABLE_STARTING'
   52 | int   posix_memalign(void **__memptr, size_t __alignment, size_t __size) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
      |
~~~~~~~~~
In file included from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:144:1: error: expected declaration specifiers before 'div_t'
  144 | div_t  div(int, int) __pure2;
      | ^~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:149:1: error: expected declaration specifiers before 'ldiv_t'
  149 | ldiv_t  ldiv(long, long) __pure2;
      | ^~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:153:1: error: expe
cted declaration specifiers before 'lldiv_t'
  153 | lldiv_t  lldiv(long long, long long);
      | ^~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:157:18: error: expected declaration specifiers or '...' before 'wchar_t'
  157 | size_t  mbstowcs(wchar_t * __restrict , const char * __restrict, size_t);
      |                  ^~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:158:13: error: expected declaration specifiers or '...' before 'wchar_t'
  158 | int  mbtowc(wchar_t * __restrict, const char * __restrict, size_t);
      |             ^~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:194:51: error: expected ';', ',' or ')' before '*' token
  194 | size_t  wcstombs(char * __restrict, const wchar_t * __restrict, size_t);
      |                                                   ^
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:195:21: error: expected declaration specifiers or '...' before 'wchar_t'
  195 | int  wctomb(char *, wchar_t);
      |                     ^~~~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:260,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types/_dev_t.h:31:31: error: storage class specified for parameter 'dev_t'
   31 | typedef __darwin_dev_t        dev_t;    /* device number */
      |                               ^~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:261,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/_types/_mode_t.h:31:33: error: storage class specified for parameter 'mode_t'
   31 | typedef __darwin_mode_t         mode_t;
      |                                 ^~~~~~
In file included from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:270:53: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__OSX_AVAILABLE_STARTING'
  270 | void  arc4random_buf(void * __buf, size_t __nbytes) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:273:46: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__OSX_AVAILABLE_STARTING'
  273 |   arc4random_uniform(uint32_t __upper_bound) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
      |
In file included from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:292:45: error: expected ',' or ';' before '__OSX_AVAILABLE_BUT_DEPRECATED_MSG'
  292 | int  daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0, __MAC_10_5, __IPHONE_2_0, __IPHONE_2_0, "Use posix_spawn APIs instead.") __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
      |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:294:31: error: expected ')' before 'char'
  294 | char *devname_r(dev_t, mode_t, char *buf, int len);
      |                               ^~~~~
      |                               )
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:325:6: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__OSX_AVAILABLE_STARTING'
  325 |      __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
      |      ^~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:333:6: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__OSX_AVAILABLE_STARTING'
  333 |      __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
      |      ^~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:356:14: error: storage class specified for parameter 'suboptarg'
356 | extern char *suboptarg;  /* getsubopt(3) external variable */
      |              ^~~~~~~~~
In file included from counter.c:8:
counter.h:6:24: error: storage class specified for parameter 'Counter'
    6 | typedef struct counter Counter;
      |                        ^~~~~~~
counter.h:9:1: error: expected declaration specifiers before 'Counter'
    9 | Counter *counterCreate(void);
      | ^~~~~~~
counter.h:10:21: error: expected declaration specifiers or '...' before 'Counter'
   10 | void counterDestroy(Counter *);
      |                     ^~~~~~~
counter.h:11:22: error: expected declaration specifiers or '...' before 'Counter'
   11 | int counterIncrement(Counter *);
      |                      ^~~~~~~
counter.c:11:1: warning: empty declaration
   11 | struct counter {
      | ^~~~~~
counter.c:18:1: error: expected declaration specifiers before 'Counter'
   18 | Counter *counterCreate(void)
      | ^~~~~~~
counter.c:30:21: error: expected declaration specifiers or '...' before 'Counter'
   30 | void counterDestroy(Counter *c)
      |                     ^~~~~~~
counter.c:36:22: error: expected declaration specifiers or '...' before 'Counter'
   36 | int counterIncrement(Counter *c)
      |                      ^~~~~~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/wait.h:110,
                 from /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/stdlib.h:66,
                 from counter.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/resource.h:447:9: error: old-style parameter declarations in prototyped function definition
  447 | int     getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
      |         ^~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/resource.h:447:24: error: parameter name omitted
  447 | int     getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
      |                        ^~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/resource.h:447:29: error: parameter name omitted
  447 | int     getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
      |                             ^~~
counter.c:39: error: expected '{' at end of input
      |                        ^~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/sys/resource.h:447:29: error: parameter name omitted
  447 | int     getiopolicy_np(int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
      |                             ^~~
counter.c:39: error: expected '{' at end of input
   39 | }
      |
counter.c:39: warning: control reaches end of non-void function [-Wreturn-type]
   39 | }
      |


  

Я буду признателен за любую помощь, чтобы понять, почему эта ошибка с gcc. Заранее всем спасибо.

Комментарии:

1.Это похоже на проблему с вашей установкой gcc. Можете ли вы скомпилировать файл, содержащий только #include<stdlib.h> ?

2. Кроме того, это точное содержимое counter.c ? Вывод компилятора предполагает, что перед тем, что вы показываете, есть еще 4 строки.

3. Ошибки исходят из #include <stdlib.h> того, что было раньше #include "counter.h" . Невозможно, чтобы причиной этого мог быть код счетчика.

4. Работает ли gcc с OSX в наши дни?