【发布时间】:2014-01-01 20:59:09
【问题描述】:
此代码的输出打印出“成功”。
printf("%m\n");
【问题讨论】:
标签: c printf glibc errno format-specifiers
此代码的输出打印出“成功”。
printf("%m\n");
【问题讨论】:
标签: c printf glibc errno format-specifiers
m 转换说明符不是 C,而是printf 的 GNU 扩展:
来自 GNU 文档:
http://www.gnu.org/software/libc/manual/html_node/Other-Output-Conversions.html
'%m' 转换打印与 errno 中的错误代码对应的字符串。请参阅错误消息。因此:
fprintf (stderr, "can't open `%s': %m\n", filename);相当于:
fprintf (stderr, "can't open `%s': %s\n", filename, strerror (errno));“%m”转换是 GNU C 库扩展。
所以:
printf("%m\n", d);
等价于
printf("%s\n", strerror (errno), d);
相当于
printf("%s\n", strerror (errno));
请注意,%m 不需要参数。这里printf("%m\n", d) 和printf("%s\n", strerror (errno), d) 的参数比需要的多:printf 如果有额外的尾随参数,它们只会被评估和忽略。
【讨论】:
%m 添加一个额外的参数。
其实printf()关于%m的手册很简洁:
m (Glibc extension; supported by uClibc and musl.) Print output
of strerror(errno). No argument is required.
但是 strerror() 在多线程程序中有一个问题:它不可重入。线程安全版本是strerror_r()。
对GLIBC implementation 的一点研究表明,%m 实际上等同于 strerror_r()。因此 %m 是线程安全的!
【讨论】: