Help with simple C statement

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
Hi, I'm not a C fundi and I've googled a bit but haven't come up with an answer...
My son is studying at the mo and doing a programming module at uni - they're using C. What I can't yet answer is why the
Code:
	setbuf(stdout, 0);
statement is required in the code below:

Code:
#include <stdio.h>

int main () {
	int num1, num2, ans;
	
[B]	//setbuf(stdout, 0);[/B]

	printf("Please enter the first integer:\n");
	scanf("%d",&num1);

	printf("Please enter the second integer:\n");
	scanf("%d",&num2);

	ans=num1+num2;
	printf ("\n%d + %d = %d", num1, num2, ans);

	return 0;
}

The code fires and appears to produce the same result with or without it... is there a reason it's included? Is this perhaps a 'best practice' situation where you want to be sure there isn't a buffer set? Any help is appreciated!
 

MagicDude4Eva

Banned
Joined
Apr 2, 2008
Messages
6,479
In Linux you can specify various constants and it typically describes how your program buffers data on output. I can't remember the constants, but it is unbuffered, line buffered and some other buffer. I think the 0 means unbuffered stdout.
 

cguy

Executive Member
Joined
Jan 2, 2013
Messages
8,527
Setbuf called like that (NULL pointer), will disable buffering, and allow you to see the printed text immediately. The reason you are not seeing a difference is because \n will flush the buffer anyway. If you remove \n from the strings, you should see unwanted behavior, such as the text not being printed out, before waiting for your fscanf input. In general I never use use setbuf, I let \n cause my buffers to flush, or explicitly call fflush(...).
 
Last edited:

cguy

Executive Member
Joined
Jan 2, 2013
Messages
8,527
In Linux you can specify various constants and it typically describes how your program buffers data on output. I can't remember the constants, but it is unbuffered, line buffered and some other buffer. I think the 0 means unbuffered stdout.

The parameter there is just the buffer pointer to use. Null means no buffering. This just makes a call to setvbuf though, which has all the flags I expect you are thinking of.
 

gkm

Expert Member
Joined
May 10, 2005
Messages
1,519
setbuf with a 0 (null buffer), makes stdout unbuffered, which means that all the output is immediately push to the output, a character at a time. As far as I know the default for stdout is usually line buffered, which means it is written a line at a time. My opinion is there is no point in having that statement in this case, in fact it might make the program very slightly slower, but I do not think there will be any other perceptible effect.
 

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
Setbuf called like that (NULL pointer), will disable buffering, and allow you to see the printed text immediately. The reason you are not seeing a difference is because \n will flush the buffer anyway. If you remove \n from the strings, you should see unwanted behavior, such as the text not being printed out, before waiting for your fscanf input. In general I never use use setbuf, I let \n cause my buffers to flush, or explicitly call fflush(...).

It behaves the same on Windows with and without the setbuf and \n
All \n appears to do is a carriage return...

My theory is it's best practice - to ensure there is no buffer right before your output in case one was set elsewhere in code - in other words it's explicit... either that or it indeed behaves differently in Linux without specifying it...
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282

cguy

Executive Member
Joined
Jan 2, 2013
Messages
8,527
[)roi(];18033234 said:
You're correct that in your code example; setbuf(stdout, 0); is doing nothing.

Basically the command is redirecting stdout (the standard output stream) to 0; zero being the equivalent of a C null memory pointer. i.e. disable previous redirection
FYI a more common use of setbuf or setvbuf this command is used to redirect Probably the commonest use of setbuf() or setvbuf() is make an output stream line-buffered or unbuffered.

It doesn't redirect, it just changes the buffering. If you specific a buffer, data will go to that buffer, but will still land up at stdout (unless redirected by other means), when it is flushed.
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
Setbuf called like that (NULL pointer), will disable buffering, and allow you to see the printed text immediately. The reason you are not seeing a difference is because \n will flush the buffer anyway. If you remove \n from the strings, you should see unwanted behavior, such as the text not being printed out, before waiting for your fscanf input. In general I never use use setbuf, I let \n cause my buffers to flush, or explicitly call fflush(...).
Looks like I was slow to respond; guess it was that coffee break in the middle.
Great summary.
The only place I typically use setbuf is to circumvent delays with continual flushing of the stdout buffer. i.e. for performance reasons: when your IO rate is high, and you prefer to have control over flushing to a stream.
 
Last edited:

cguy

Executive Member
Joined
Jan 2, 2013
Messages
8,527
It behaves the same on Windows with and without the setbuf and \n
All \n appears to do is a carriage return...

My theory is it's best practice - to ensure there is no buffer right before your output in case one was set elsewhere in code - in other words it's explicit... either that or it indeed behaves differently in Linux without specifying it...

I believe you are correct here - if the output environment chooses not to buffer, then you will get the same result regardless of setbuf(stdout,0), but this isn't always guaranteed.
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
It doesn't redirect, it just changes the buffering. If you specific a buffer, data will go to that buffer, but will still land up at stdout (unless redirected by other means), when it is flushed.
You're correct; covered it in the detail, screwed up the summary.
 

cguy

Executive Member
Joined
Jan 2, 2013
Messages
8,527
[)roi(];18033286 said:
Looks like I was slow to respond; guess it was that coffee break in the middle.
Great summary.
The only place I typically use setbuf is to circumvent delays with continual flushing of the stdout buffer. i.e. for performance reasons: when your IO rate is high, and you prefer to have control over when flushing to a stream.

Agreed - more flushes means slower output.
 

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
Thanks everyone, very helpful... another q - could two different compilers output an exe that behaves differently in Windows, or do all compilers output identical binary? I'm assuming, provided your compiler adheres to the same standard, it shouldn't matter which compiler you use...
 

cguy

Executive Member
Joined
Jan 2, 2013
Messages
8,527
Thanks everyone, very helpful... another q - could two different compilers output an exe that behaves differently in Windows, or do all compilers output identical binary? I'm assuming, provided your compiler adheres to the same standard, it shouldn't matter which compiler you use...

Because of various language and OS standards, the odds of them producing binaries with the same behaviour is very likely (you would have to do something pretty esoteric for this not to happen), although, by no means guaranteed - different implementations vary from the specs in subtle ways (the specs sometimes being a little ambiguous themselves). The odds of them producing the same binary, however is extremely unlikely, since the actual assembler/machine-code generated will likely be different because of the different compiler conventions and heuristics used.
 
Top