Question

I am using gcc compiler on linux.

When I run this code (Notice"\n" is not present after hello world in printf)

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
    printf("Hello world");
    fork();
}

I GET THIS OUTPUT: Hello worldHello world

On the other hand When I run this code (Notice"\n" is present after hello world in printf)

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
    printf("Hello world\n");
    fork();
}

I GET THIS OUTPUT: Hello world

Can someone describe in detail that, why omitting or leaving "\n" prints "Hello world" twice?

Was it helpful?

Solution 2

Not having the \n means that "hello world" is still in memory - ready to go one its merry way to the terminal.

fork will make a duplicate of this memory - i.e. now you have two processes with the same "hello world" in memory. When the program terminates it will flush this to stdout. I.e. getting it twice.

But if you put the \n in - it gets flush to stdout immediately. Hence this buffer will be empty before the fork is called.

OTHER TIPS

To elaborate on the answer in the linked question and relate it to your question, stdout generally buffers input until it sees a \n, or you explicitly fflush it.

When you have the \n there, you are making it flush before the fork(). Without the \n, it flushes after the fork, so it will exist in both processes.

In the linked question, they talk about fflush(), but \n has the same effect of causing stdout to flush.

You will see only one print with the program below as well:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>

int main()
{
    printf("Hello world");
    fflush(stdout);
    fork();
}

Edit: Due to a comment from Dabo, \n will only cause a flush if stdout is in line buffering mode instead of full buffering mode. We can observe in the following program that we still see the string printed twice, even with \n, when full buffering mode is turned on using setvbuf.

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
    setvbuf(stdout, NULL,_IOFBF, BUFSIZ);
    printf("Hello world\n");
    fork();
}

Output:

Hello world
Hello world

I would say both versions are incorrect. The C runtime will register atexit handlers to flush standard buffers when exit() is called. The proper way to cause your program print only once is to call _exit(0); in child process. This way your child won't call atexit ( which in turn won't flush buffers twice)

if (fork() == 0)
    _exit(0);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top