推 loveflames:在程式開頭加上setbuf(stdout,buf);也會馬上跑flush? 09/16 23:43
void __cdecl setbuf (FILE *stream, char *buffer)
{
if (buffer == NULL)
setvbuf(stream, NULL, _IONBF, 0);
else
setvbuf(stream, buffer, _IOFBF, BUFSIZ);
}
int __cdecl setvbuf (FILE *str, char *buffer, int type, size_t size)
{
REG1 FILE *stream;
int retval=0; /* assume good return */
stream = str;
_lock_str(stream);
__try {
_flush(stream);
_freebuf(stream);
(以上仍然略掉了部份程式碼)
看來 setbuf 是一定會跑 _flush 的
※ 編輯: james732 來自: 140.117.171.46 (09/17 00:02)
→ loveflames:啊啊,我的意思是程式開頭用setbuf,然後輸出到stdout 09/17 00:32
→ loveflames:最後輸出到stderr,看前面的stdout是不是馬上flush 09/17 00:33
原來是這樣 XDD 我誤解了
int main(void)
{
char buf[1024];
setbuf(stdout, buf);
printf("Hello");
fprintf(stderr, "Oh!");
}
測試的結果是...
----
Oh!
----
並沒有馬上被 fflush 出去
我又去挖了一下 code, 發現了奇怪的現象:
int __cdecl printf (const char *format, ...)
{
va_list arglist;
int buffing;
int retval;
va_start(arglist, format);
_lock_str2(1, stdout);
__try {
buffing = _stbuf(stdout);
/* 如果沒有 setbuf,那麼這個 buffing 就是 1, 反之為 0 */
retval = _output_l(stdout,format,NULL,arglist);
_ftbuf(buffing, stdout);
}
再把 _ftbuf 看仔細一點:
void __cdecl _ftbuf (int flag, FILE *str)
{
REG1 FILE *stream = str;
if (flag) { /* 如果沒有 setbuf,那麼這個 flag 就是 1, 反之為 0 */
if (stream->_flag & _IOFLRTN) {
/* Flush the stream and tear down temp buffering. */
_flush(stream);
stream->_flag &= ~(_IOYOURBUF | _IOFLRTN);
stream->_bufsiz = 0;
stream->_base = stream->_ptr = NULL;
}
}
}
在關鍵的 _stbuf 裡,有段奇怪的程式碼:
/* Make sure the stream is not already buffered. */
if (anybuf(stream))
return(0);
如果有 setbuf, 那麼這裡就會直接 return 了
不過那個 anybuf 似乎不是個真的 function,按 F11 跳不進去,無法再追 orz
我前文說「這些 _flush 一定會被執行」倒是個很大的失誤,真是不好意思 XD
※ 編輯: james732 來自: 140.117.171.46 (09/17 00:57)
→ loveflames:Hello沒印出來對吧,因為最後的fflush()是由exit()呼叫 09/17 10:59
→ loveflames:的,buf那時已經沒了 09/17 11:00
→ james732:覺得這裡的機制好像比想像中的還要複雜些 XD 09/17 11:07