问题描述
我正在树莓派上编写一些串行代码,并切换到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 \
使用-M显示2个termios.h标头.前者不包含CRTSCTS的定义,而后者则包含.
我认为标准的c89使用的不是好的,而c99使用的不是,但是我不确定,因为-M调用的结果是相同的.谁能向我解释为什么我切换到C99时会发生这种情况以及如何解决?
-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
对于c99和gnu99,此行为相同!
就像卡梅伦所说,-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 \
在定义__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 */
让我们看一下__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
第一个,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
并且在定义_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
I'm writing some serial code on a raspberry pi and switched to C99. When I did I started getting the error "error: ‘CRTSCTS’ undeclared (first use in this function)"
$ 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 \
using -M reveals 2 termios.h headers. the former does not contain a definition for CRTSCTS and the latter does.
I assume the standard c89 is using the good one and c99 not but I'm not sure since the result of the -M call is identical. Can anyone explain to me why this is happening when I switch to C99 and how to fix it?
-std=gnu99
is the solution. More detailed below.
Result of the gcc/c99 -M call is identical but it does not mean anything! The explanation of this behavior are preprocessor macros (specifically GNU extensions, like said Mat).
In detail:
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
This behavior is the same for c99 and gnu99!
Like said Cameron, -M output is identical:
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 \
CRTSCTS is defined in the bits/termios.h when __USE_MISC is defined
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 */
Let's look at __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
First one, features.h, contains definition of __USE_MISC, but only when _BSD_SOURCE or _SVID_SOURCE is defined
grep 'define __USE_MISC' /usr/include/features.h -B 1 | nl
1 #if defined _BSD_SOURCE || defined _SVID_SOURCE
2 # define __USE_MISC 1
and _BSD_SOURCE and _SVID_SOURCE is defined when _GNU_SOURCE or 'nothing' is defined
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
这篇关于当编译为C99时CRTSCTS未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!