make 给了我一个我不理解 TurboC 的错误

make gives me a error I don't understand with TurboC

我正在努力学习 C,只是为了好玩。 我正在使用 Linux 发行版。 我正在尝试编译一个使用 kbhit() 的程序。 我用 TurboC (http://www.sandroid.org/TurboC/#Download) 找到了解决这个问题的方法。

我按照说明操作,但 make 给了我这个:

gettext.c: Dans la fonction « gettextTurboC »:
gettext.c:93:13: warning: les cibles pointées dans l'affectation de « int8_t * » {alias « signed char * »} vers « uint8_t * » {alias « unsigned char * »} diffèrent dans la plage signée [-Wpointer-sign]
   TurboData = (int8_t *) dest;
             ^
In file included from TurboC.h:60,
                 from conio.h:49,
                 from gettext.c:42:
TurboC.h:250:14: error: expected « ) » before « int32_t »
 #define long int32_t
              ^~~~~~~
/usr/include/curses.h:1238:66: note: dans l'expansion de la macro « long »
 #define PAIR_NUMBER(a) (NCURSES_CAST(int,((NCURSES_CAST(unsigned long,(a)) & A_COLOR) >> NCURSES_ATTR_SHIFT)))
                                                                  ^~~~
gettext.c:124:10: note: pour correspondre à ce « ( »
  Color = PAIR_NUMBER (ch & A_COLOR);
          ^~~~~~~~~~~
gettext.c:125:23: warning: les cibles pointées dans le passage de l'argument 2 de « pair_content » diffèrent dans la plage signée [-Wpointer-sign]
  pair_content (Color, &dFore, &dBack);
                       ^~~~~~
In file included from TurboC.h:60,
                 from conio.h:49,
                 from gettext.c:42:
/usr/include/curses.h:746:28: note: « short int * » attendu mais l'argument est de type « uint16_t * » {alias « short unsigned int * »}
 extern NCURSES_EXPORT(int) pair_content (NCURSES_PAIRS_T,NCURSES_COLOR_T*,NCURSES_COLOR_T*);  /* implemented */
                            ^~~~~~~~~~~~
gettext.c:125:31: warning: les cibles pointées dans le passage de l'argument 3 de « pair_content » diffèrent dans la plage signée [-Wpointer-sign]
  pair_content (Color, &dFore, &dBack);
                               ^~~~~~
In file included from TurboC.h:60,
                 from conio.h:49,
                 from gettext.c:42:
/usr/include/curses.h:746:28: note: « short int * » attendu mais l'argument est de type « uint16_t * » {alias « short unsigned int * »}
 extern NCURSES_EXPORT(int) pair_content (NCURSES_PAIRS_T,NCURSES_COLOR_T*,NCURSES_COLOR_T*);  /* implemented */
                            ^~~~~~~~~~~~
make: *** [Makefile:126: gettext.o] Error 1

我真的不知道如何处理这个错误:

TurboC.h:250:14: error: expected « ) » before « int32_t »
#define long int32_t

有人可以帮助我吗?

您尝试使用的 "TurboC" 项目可能只适用于作者计算机的特定 gcc 版本上的简单程序。错误消息表明存在重大的、无法解决的问题。我建议不要尝试使用它。

相反,您可以通过其他一些不涉及尝试构建 Turbo C 源代码的方式来学习 C。如果您正在寻找类似的东西,那么可以搜索 ncurses 示例程序或教程。

一旦你更好地学习了这门语言,你就可能能够回到你现在正在查看的原始源代码,并能够将它直接移植到 ncurses。

免责声明:我把学习 Turbo C 在我们这个世纪有用的问题放在一边。

问题出在TurboC.h:250:

处的宏定义
#define long int32_t

这是试图通过 int32_t 重新定义内置类型 long。后者在 stdint.h 中定义,由编译器供应商提供。 int32_t 的定义是这样的,它最终映射到一个 32 位长的内置有符号整数类型。鉴于在现代主流架构上 int 是 32 位长,int32_t 的典型定义如下所示:

typedef int int32_t;

无论如何,int32_t 是一个类型定义名称。

通过 int32_tlong 定义为宏意味着所有后续出现的标记 long 都将替换为标记 int32。除了其他后果之外,这破坏了像 unsigned long 这样的合法构造:在宏扩展之后,这个构造被呈现为 unsigned int32_t.

现在,将 unsigned 与 typedef-name 结合使用是非法的。 C 语法指定要指定整数类型,我们必须使用 或者 typedef-name 关键字的组合,例如 unsignedlong,但不能同时。

GCC 报告此错误的方式有些令人困惑。在处理语句时,

Color = PAIR_NUMBER (ch & A_COLOR);

它扩展了类似函数的宏 PAIR_NUMBER,它的定义方式包含一系列标记 unsignedlonglong 然后进一步扩展为 int32_t,这会产生一个标记序列 unsignedint32_t。在扩展的地方,编译器不希望在 unsigned 之后有一个 typedef-name,因为语法禁止这样做。

然后它假定这种无效的标记组合是某处缺少右括号的结果。这种假设在这种情况下是错误的,并导致令人困惑的错误消息。

I am trying to learn C, for fun. I am using a Linux distro.

Linux 发行版是学习 C 的绝佳选择。请注意,它由 free software, whose source code you could study. You'll learn a lot by studying the source code of small free software programs written in C (e.g. those from coreutils, or a simple shell like sash 等组成)。

如果你想学习 C 编程,首先使用 standard streams (a program which handles directly the keyboard is something complex, not for newbies) and restrict yourself to use only the C standard library 从简单的命令行程序开始。

(您问题中的代码不是标准 C 语言——因为它使用了一些外部库——;我不建议一开始尝试这样做)

稍后,当您对他们更熟悉 C programming language, you could use some external libraries. A Linux distribution has lots of them. You may need to install development packages 时,例如在 Debian 上 libncurses-dev 或在 ncurses.

上 Ubuntu

C 中一个非常重要的概念是它的 undefined behavior. Learn more about it, avoid it, be

I am trying to compile a program which uses kbhit()

请注意 kbhit<conio.h> 不在 C11 标准中(参见 n1570...), and they are not in the C standard library 所以不要不要使用它们(你不会在 Linux 或 POSIX 上找到任何直接等价物)。

在 Linux 上,您可能想要使用 ncurses. Of course, you need to spend a few days learning it and studying its documentation. You won't find a direct equivalent to kbhit. Read the NCURSES programming howto

您可能想要使用一些非标准库(Linux 有很多)。然后阅读Program Library HowTo.

终端(和terminal emulators, and the line discipline) is a complex thing. Read The TTY demystified, termios(3), pty(7). You really want to use some library such as ncurses (or perhaps readline)。

geany is not a compiler, but a source code editor. See this 回答相关问题。

您可能想使用一些 build automation tool, such as GNU make. It will run the gcc compiler for you. So read How to invoke GCC

一旦您总体上熟悉了 C 编程,您可能想了解有关 Linux 编程的更多信息,因此请阅读 ALP

PS。 TurboC is an ancient C compiler (not standard conforming) that you should even forget. It does not exist on Linux. GCC is a good, standard conforming, C compiler. You should use it with all warnings and debug info, i.e. compile yoursourcecode.c as gcc -Wall -Wextra -g yoursourcecode.c -o yourbinary on Linux. Read also How to debug small programs. The valgrind tool is also very useful (and available on Linux) to debug memory leaks.

在 Whosebug 上提问时,请务必将 locale 设置为英语。我们不应该用法语破译编译器诊断。