在 Cygwin 上使用 TCC 进行编译
我正在测试一个用 C 编写的非常基本的程序,其全部内容附在下面。在尝试执行 TCC 生成的可执行文件时,我注意到在实际看到任何 printf() 调用的输出之前,我需要为每个连续的 fgets() 输入输入。
这非常令人困惑,因此我决定尝试在标准 Windows 控制台上运行可执行文件。它运行完美,输入和输出提示以正确的顺序显示。
然而,我注意到,如果我使用 GCC 编译该程序,它可以在 Cygwin 中编译的终端上正常工作(mintty,尽管我使用 rxvt 得到了相同的结果)。
谁能解释为什么会发生这种情况,以及我如何阻止它发生?我想独立于 Cygwin 编译我的程序,同时仍然使用基于 Cygwin 的终端。
谢谢!
int main()
{
char something[12];
printf("This printf() should be outputted before you are prompted for input: ");
fgets(something, sizeof something, stdin);
printf("You entered, %s", something);
}
I was testing a very basic program written in C, the entirety of which is enclosed below. Upon attempting to execute the executable produced by TCC, I noticed that I was required to enter input for each successive fgets() prior to actually seeing output from any printf() calls.
This was very confusing, so I decided to try running the executable on the standard Windows console. It ran flawlessly, and input and output prompts were shown in the proper order.
However, I noticed that if I compiled the program with GCC it would work fine on the terminal compiled in Cygwin (mintty, though I got the same results with rxvt).
Could anyone give an explanation as to why this is happening, and how I can stop it from happening? I'd like to compile my programs independent of Cygwin while still using a Cygwin-based terminal.
Thanks!
int main()
{
char something[12];
printf("This printf() should be outputted before you are prompted for input: ");
fgets(something, sizeof something, stdin);
printf("You entered, %s", something);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这取决于标准输入和标准输出的缓冲。我不确定 C 标准对此有何规定(在 C++ 中,默认情况下流是绑定的),但您可以
在调用 printf 之后使用 : 自行刷新标准输出。
This is down to the buffering of standard input and standard output. I'm not sure what the C standard has to say about this (in C++ the streams are tied by default), but you can flush standard output yourself with :
after the call to printf.
Mintty 和 rxvt 是基于 Unix 伪终端设备的终端模拟器。 Cygwin 基于 Windows 管道 实现这些。
当您使用 Cygwin gcc 编译程序时,它会链接到 Cygwin DLL,其中包含使连接到终端的流像在 Unix 系统上那样工作的所有魔力,这意味着默认情况下是行缓冲。
但是,当您使用 tcc 编译程序时,您创建了一个本机 Windows 程序,并且只能看到底层 Windows 管道。在 Microsoft C 库中,默认情况下连接到管道的流是完全缓冲的,这就是为什么使用 fflush(stdout) 显式刷新或使用 setvbuf(stdout, NULL, _IONBF, 0 禁用缓冲) ) 有帮助。 MS 的 C 库不支持行缓冲。
Mintty and rxvt are terminal emulators based on Unix pseudo terminal devices. Cygwin implements these based on Windows pipes.
When you compile a program with Cygwin gcc, it gets linked to the Cygwin DLL, which contains all the magic for making streams connected to a terminal work as they should on a Unix system, which means line buffering by default.
However, when you compile the program with tcc, you create a native Windows program, and that only sees the underlying Windows pipes. In the Microsoft C library, streams connected to pipes are fully buffered by default, which is why flushing explicitly with
fflush(stdout)
or disabling the buffering withsetvbuf(stdout, NULL, _IONBF, 0)
helps. MS's C library does not support line buffering.标准输出流通常是行缓冲的,即当您打印换行符时缓冲区会被刷新。
您可以使用以下命令显式刷新它:
您可以使用以下命令关闭给定流
s
的缓冲:请参阅 setvbuf() 的联机帮助页 了解更多详细信息。
The standard output stream is usually line-buffered, i.e. the buffer gets flushed when you print a newline.
You may flush it explicitly with:
And you can turn off buffering for a given stream
s
with:See the manpage of setvbuf() for more details.