%m格式说明符的含义是什么?

Man*_*uel 32 c printf

此代码的输出打印出"成功".

char d='w';
printf("%m\n", d);
Run Code Online (Sandbox Code Playgroud)

oua*_*uah 41

m转换说明符不是C,但是对以下内容的GNU扩展printf:

从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);
Run Code Online (Sandbox Code Playgroud)

相当于:

fprintf (stderr, "can't open `%s': %s\n", filename, strerror (errno));
Run Code Online (Sandbox Code Playgroud)

'%m'转换是GNU C库扩展.

所以:

printf("%m\n", d);
Run Code Online (Sandbox Code Playgroud)

相当于

printf("%s\n", strerror (errno), d);
Run Code Online (Sandbox Code Playgroud)

这相当于

printf("%s\n", strerror (errno));
Run Code Online (Sandbox Code Playgroud)

请注意,%m不需要参数.这里printf("%m\n", d)printf("%s\n", strerror (errno), d)具有参数多于必需的:有printf,如果有多余的尾随参数,他们只是评估并忽略.

  • 我认为最有趣的部分是printf确实*不需要为每个`%m`提供额外的参数. (3认同)

Rac*_* K. 9

实际上,关于%m的printf()手册非常简洁:

m      (Glibc extension; supported by uClibc and musl.)  Print output
              of strerror(errno).  No argument is required.
Run Code Online (Sandbox Code Playgroud)

strerror()它不是多线程安全的:它不可重入。线程安全版本是strerror_r()

对GLIBC 实现的一点研究表明%m实际上相当于 strerror_r() 而不是 strerror()。因此%m 是线程安全的!因此,在线手册是错误的(或者至少不够准确)!