CRTSCTS在编译为C99时没有定义

Cam*_*amW 6 c c99 termios raspberry-pi

我正在写一个覆盆子pi上的一些串行代码并切换到C99.当我这样做时,我开始收到错误"错误:'CRTSCTS'未声明(首次使用此函数)"

$ c99 -M serial01.c | grep termios.h
 /usr/include/termios.h /usr/include/arm-linux-gnueabihf/bits/termios.h \
$ gcc -M serial01.c | grep termios.h
 /usr/include/termios.h /usr/include/arm-linux-gnueabihf/bits/termios.h \
Run Code Online (Sandbox Code Playgroud)

使用-M显示2个termios.h头文件.前者不包含CRTSCTS的定义,后者则不包含.

我假设标准c89使用好的和c99但我不确定,因为-M调用的结果是相同的.任何人都可以向我解释为什么当我切换到C99以及如何修复它时会发生这种情况?

hon*_*989 5

-std=gnu99是解决方案。下文更详细。

gcc / c99 -M调用的结果相同,但是没有任何意义!这种行为的解释是预处理器宏(特别是GNU扩展,如Mat所述)。

详细:

cat -n main.c
     1  #include <termios.h>
     2
     3  int printf(const char *, ...);
     4
     5  int main(void)
     6  {
     7      printf("%d\n", CRTSCTS);
     8      return 0;
     9  }
gcc main.c -o main --std=c89 -> 'CRTSCTS' undeclared compilation error
gcc main.c -o main --std=cgnu89 -> successfully compiled
Run Code Online (Sandbox Code Playgroud)

对于c99和gnu99,此行为相同!

就像Cameron所说的,-M输出是相同的:

gcc -M --std=c89 main.c | grep termios.h | nl
     1  main.o: main.c /usr/include/termios.h /usr/include/features.h \
     2   /usr/include/arm-linux-gnueabihf/bits/termios.h
gcc -M --std=gnu89 main.c | grep termios.h | nl
1  main.o: main.c /usr/include/termios.h /usr/include/features.h \
     2   /usr/include/arm-linux-gnueabihf/bits/termios.h \
Run Code Online (Sandbox Code Playgroud)

当定义__USE_MISC时,在bits / termios.h中定义CRTSCTS

     1  #ifdef __USE_MISC
     2  # define CIBAUD   002003600000          /* input baud rate (not used) */
     3  # define CMSPAR   010000000000          /* mark or space (stick) parity */
     4  # define CRTSCTS  020000000000          /* flow control */
Run Code Online (Sandbox Code Playgroud)

让我们看一下__USE_MISC。

gcc -M /usr/include/termios.h | nl
     1  termios.o: /usr/include/termios.h /usr/include/features.h \
     2   /usr/include/arm-linux-gnueabihf/bits/predefs.h \
     3   /usr/include/arm-linux-gnueabihf/sys/cdefs.h \
     4   /usr/include/arm-linux-gnueabihf/bits/wordsize.h \
     5   /usr/include/arm-linux-gnueabihf/gnu/stubs.h \
     6   /usr/include/arm-linux-gnueabihf/bits/types.h \
     7   /usr/include/arm-linux-gnueabihf/bits/typesizes.h \
     8   /usr/include/arm-linux-gnueabihf/bits/termios.h \
     9   /usr/include/arm-linux-gnueabihf/sys/ttydefaults.h
Run Code Online (Sandbox Code Playgroud)

第一个,features.h,包含__USE_MISC的定义,但仅当定义了_BSD_SOURCE或_SVID_SOURCE时

grep 'define __USE_MISC' /usr/include/features.h -B 1 | nl
     1  #if defined _BSD_SOURCE || defined _SVID_SOURCE
     2  # define __USE_MISC     1
Run Code Online (Sandbox Code Playgroud)

定义_GNU_SOURCE或'nothing'时定义_BSD_SOURCE和_SVID_SOURCE

     1  #ifdef _GNU_SOURCE
     2  # undef  _ISOC95_SOURCE
     3  # define _ISOC95_SOURCE 1
     4  # undef  _ISOC99_SOURCE
     5  # define _ISOC99_SOURCE 1
     6  # undef  _POSIX_SOURCE
     7  # define _POSIX_SOURCE  1
     8  # undef  _POSIX_C_SOURCE
     9  # define _POSIX_C_SOURCE        200809L
    10  # undef  _XOPEN_SOURCE
    11  # define _XOPEN_SOURCE  700
    12  # undef  _XOPEN_SOURCE_EXTENDED
    13  # define _XOPEN_SOURCE_EXTENDED 1
    14  # undef  _LARGEFILE64_SOURCE
    15  # define _LARGEFILE64_SOURCE    1
    16  # undef  _BSD_SOURCE
    17  # define _BSD_SOURCE    1
    18  # undef  _SVID_SOURCE
    19  # define _SVID_SOURCE   1
    20  # undef  _ATFILE_SOURCE
    21  # define _ATFILE_SOURCE 1
    22  #endif

    23  /* If nothing (other than _GNU_SOURCE) is defined,
    24     define _BSD_SOURCE and _SVID_SOURCE.  */
    25  #if (!defined __STRICT_ANSI__ && !defined _ISOC99_SOURCE && \
    26       !defined _POSIX_SOURCE && !defined _POSIX_C_SOURCE && \
    27       !defined _XOPEN_SOURCE && !defined _BSD_SOURCE && !defined _SVID_SOURCE)
    28  # define _BSD_SOURCE    1
    29  # define _SVID_SOURCE   1
    30  #endif
Run Code Online (Sandbox Code Playgroud)