Re: [問題] fflush 問題
以下是在 VS2008 用單步執行跳出來的 code
先來看一下 fflush 的部份實作碼(其他不重要):
int __cdecl fflush (REG1 FILE *stream)
{
__try {
rc = _fflush_nolock(stream);
}
}
再往下追,就會看到:
int __cdecl _fflush_nolock (REG1 FILE *str)
{
if (_flush(str) != 0) {
/* _flush failed, don't attempt to commit */
return(EOF);
}
}
fflush 看到這裡就夠了,因為接下來看 printf 有這麼一行:
int __cdecl printf (const char *format, ...)
{
_ftbuf(buffing, stdout);
}
再往下追,可以看到:
void __cdecl _ftbuf (int flag, FILE *str)
{
REG1 FILE * stream = str;
_flush(stream);
}
雖然挖到的 code 大部份我都看不懂 XD
不過應該可以得到:「 printf 底層會呼叫 fflush 底層」這樣的結論
因此,每次呼叫 printf,效果就跟 printf + fflush(stdout); 相同
對了,我抓出來的 code 都不在 branch 裡,是正常情況一定會執行到的~
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.117.171.46
※ 編輯: james732 來自: 140.117.171.46 (09/16 23:37)
推
09/16 23:43, , 1F
09/16 23:43, 1F
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)
→
09/17 00:32, , 2F
09/17 00:32, 2F
→
09/17 00:33, , 3F
09/17 00:33, 3F
原來是這樣 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)
→
09/17 10:59, , 4F
09/17 10:59, 4F
→
09/17 11:00, , 5F
09/17 11:00, 5F
→
09/17 11:07, , 6F
09/17 11:07, 6F
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章