使用stdout和stderr禁用缓冲是否安全?

Jee*_*tel 11 c linux stdout buffering stderr

有时我们会以这种方式在代码中添加一些调试打印

printf("successfully reached at debug-point 1\n"); 

some code is here

printf("successfully reached at debug-point 2"); 
Run Code Online (Sandbox Code Playgroud)

现在在这种情况下只有debug-point1将在stdio上打印调试点2打印被写入stdio缓冲区但是它没有刷新因为它没有得到printf所以我们认为崩溃发生在debug-point1之后

如果我像这样禁用stdio和stderr流的缓冲选项,那么就来自于此

setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
Run Code Online (Sandbox Code Playgroud)

那么这样做是否安全?

为什么所有流都默认为行缓冲?

编辑:

通常,对于任何文件流,默认分配缓冲区的大小是多少?我认为它的依赖.我想知道Linux?

cni*_*tar 7

为什么所有流默认情况下都是行缓冲的

由于性能原因,它们被缓冲。该库会尽力避免进行系统调用,因为它需要很长时间。而且并非所有默认情况下都被缓冲。例如stderr通常是无缓冲的,并且stdout仅在引用tty时才是行缓冲的。

那么这样做安全吗?

禁用缓冲是安全的,但是我必须说这不是最好的调试技术。


Bas*_*tch 7

一种可能的方法可能是拥有一个bool dodebug全局标志并定义一个宏,例如

#ifdef NDEBUG
#define debugprintf(Fmt,...) do{} while(0)
#else
#define debugprintf(Fmt,...) do {if (dodebug) {                 \
   printf("%s:%d " Fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
   fflush(stdout); }} while(0)
#endif
Run Code Online (Sandbox Code Playgroud)

然后在你的代码中,有一些

debugprintf("here i=%d", i);
Run Code Online (Sandbox Code Playgroud)

当然,您可以在上面的宏中fprintf改为...注意fflush格式的附加换行符.

出于性能原因,应该避免禁用缓冲.