Search code examples
cterminalcygwinprintffgets

Compiling with TCC on Cygwin


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);
}

Solution

  • 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 with setvbuf(stdout, NULL, _IONBF, 0) helps. MS's C library does not support line buffering.