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?
为什么所有流默认情况下都是行缓冲的
由于性能原因,它们被缓冲。该库会尽力避免进行系统调用,因为它需要很长时间。而且并非所有默认情况下都被缓冲。例如stderr,通常是无缓冲的,并且stdout仅在引用tty时才是行缓冲的。
那么这样做安全吗?
禁用缓冲是安全的,但是我必须说这不是最好的调试技术。
一种可能的方法可能是拥有一个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格式的附加换行符.
出于性能原因,应该避免禁用缓冲.