dprintf的跨平台兼容性
Linux 有一个很好的函数 dprintf
:
函数
dprintf()
和vdprintf()
(在 glibc2 库中找到)与fprintf()
和 < code>vfprintf(),不同之处在于它们输出到文件描述符 fd 而不是给定的流。
然而,正如同一消息来源指出的那样:
这些函数是 GNU 扩展,而不是 C 或 POSIX 中的函数。显然,这些名字选得不好。许多系统(如 MacOS)都有名为 dprintf() 的不兼容函数,通常是
printf() 的一些调试版本,可能具有类似的原型
void dprintf (int level, const char *format, ...);
其中第一个参数是调试级别(输出到
stderr
)。此外,dprintf()
(或DPRINTF
)也是调试printf
的流行宏名称。因此,可能最好在可移植的程序中避免使用此功能。
我的问题
如何进行设置,以安全地调用我想要的 dprintf(如果存在),或者如果该函数不存在,则无法编译并显示一些合理的错误消息?我想我会做这样的事情:
#ifdef SOMETHING
#define Dprintf dprintf
#else
#error "no dprintf"
#endif
但我不知道 SOMETHING
应该是什么。我想我可以将其限制为仅适用于 Linux,但我可以让它更宽松吗?
Linux has this nice function dprintf
:
The functions
dprintf()
andvdprintf()
(as found in the glibc2 library) are exact analogues offprintf()
andvfprintf()
, except that they output to a file descriptor fd instead of to a given stream.
however as that same source points out:
These functions are GNU extensions, not in C or POSIX. Clearly, the names were badly chosen. Many systems (like MacOS) have incompatible functions called
dprintf()
, usually some debugging version ofprintf()
, perhaps with a prototype like
void dprintf (int level, const char *format, ...);
where the first parameter is a debugging level (and output is to
stderr
). Moreover,dprintf()
(orDPRINTF
) is also a popular macro name for a debuggingprintf
. So, probably, it is better to avoid this function in programs intended to be portable.
My question
How can I make a setup that will safely call the dprintf
that I want, if it exists, or fail to compile with some reasonably sane error message if that function doesn't exist? I guess I'd do something like this:
#ifdef SOMETHING
#define Dprintf dprintf
#else
#error "no dprintf"
#endif
but I don't know what SOMETHING
should be. I guess I could restrict it to just Linux but could I make it looser?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看起来
dprintf()
实际上在 POSIX.1- 2008 (具有您想要的语义),因此您可以执行以下操作:如果您使用的是 gnu 构建系统,则定义
__GLIBC__
。在不编写小型测试程序的情况下,这可能是最安全的。Looks like
dprintf()
is actually in POSIX.1-2008 (with the semantics you want), so you can do this:__GLIBC__
is defined if you're using a gnu build system. This is probably as safe as you can be without writing a small test program.如果您在构建系统中使用自动工具,则可以进行自动配置测试。
(交叉编译时允许使用
--with-dprintf
或--without-dprintf
,因为AC_RUN_IFELSE
在这些情况下无效。 )fdopen 不是标准 C 语言,但是< /em> 在 POSIX.2 及更高版本中。我不记得任何类似 UNIX 的系统没有它——哎呀,甚至 Windows 也有它。
当然,如果您知道要打印到哪个文件描述符,只需保留 FILE* 指针即可。
You could make an autoconf test, if you're using autotools for your buildsystem.
(Allowing for
--with-dprintf
or--without-dprintf
when cross-compiling, asAC_RUN_IFELSE
isn't valid in those cases.)fdopen isn't in standard C, but it is in POSIX.2 and later. I don't recall any UNIX-like that doesn't have it -- heck, even Windows has it.
Of course, if you know which file descriptor you'll be printing to, just keep the
FILE*
pointer around instead.Autoconf 测试可以检查 dprintf(1, "blablabla") 是否写入 stdout 或 stderr,以及 dprintf(-1, "blablabla") 是否以有趣的方式失败或写入 stderr。
如果 libc 给出了错误的
dprintf()
,您可以在snprintf()
之上自己实现它(或者更好的asprintf()
) ) 和 write()。然后向链接器提及你的“dprintf.o”,这样它就更喜欢你的而不是 libc 的。如果你想要一个更好的名字,我建议
fdprintf()
。An Autoconf test could check whether
dprintf(1, "blablabla")
writes to stdout or stderr, and whetherdprintf(-1, "blablabla")
fails in an interesting way or writes to stderr.If libc gives you with the wrong
dprintf()
, you could implement it yourself on top ofsnprintf()
(or even betterasprintf()
) andwrite()
. And then mention your 'dprintf.o' to the linker so it prefers yours to libc's.If you want a better name, I propose
fdprintf()
.