我一直在阅读info libc
,在2.3节“错误报告-错误消息”中提到了以下两个函数:
--功能:const char * strerrorname_np(int ERRNUM)
| MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety Concepts::.
This function returns the name describing the error ERRNUM or
‘NULL’ if there is no known constant with this value (e.g >"EINVAL"
for ‘EINVAL’).
This function is a GNU extension, declared in the header file
‘string.h’.
字符串
--功能:const char * strerrordesc_np(int ERRNUM)
| MT-Safe | AS-Safe | AC-Safe | *Note POSIX Safety Concepts::.
This function returns the message describing the error ERRNUM or
‘NULL’ if there is no known constant with this value (e.g >"Invalid
argument" for ‘EINVAL’). Different than ‘strerror’ the returned
description is not translated.
型
但是这些函数在我的Linux(Ubuntu)机器上并不像预期的那样工作。它们可以编译,但会导致一个警告,说我试图在'char *'所属的类型中使用'int'。此外,当程序运行时,它导致seg故障。
下面是一些示例代码,我故意滥用fopen来生成errno,然后尝试使用上述函数:
#include <errno.h> /* errno */
#include <stdio.h> /* printf */
#include <string.h> /* <-- functions should be here! */
void error_reporting_example(void)
{
/* to generate an error, I'll pass fopen a bad flag */
FILE * file = fopen("some_file", "bad_flags");
if(file == NULL)
{
int errno_saved = errno;
printf("ERROR: fopen failed with errno = %d\n\tError Name: %s\n\tError Description: %s\n",
errno_saved,
strerrorname_np(errno_saved),
strerrordesc_np(errno_saved));
}
}
型
结果输出为
$ ./test
ERROR: fopen failed with errno = 22
Segmentation fault (core dumped)
型
考虑到我的文档已经过时或者libc不兼容,我验证了string. h中函数prototyptes的存在
$ grep -rns /usr/include -e 'strerrordesc_np'
/usr/include/string.h:450:extern const char *strerrordesc_np (int __err) __THROW;
$ grep -rns /usr/include -e 'strerrorname_np'
/usr/include/string.h:452:extern const char *strerrorname_np (int __err) __THROW;
型
我运行带有-H标志的gcc来列出在编译有问题的文件时使用的头文件,以验证是否包含/usr/include/string. h
1条答案
按热度按时间mkshixfv1#
在the man page中比在信息文档中更明显地说明了它,但是由于
strerrordesc_np()
和strerrorname_np()
是GNU扩展,因此在包含任何头文件之前需要定义_GNU_SOURCE
feature test macro,以便使这些函数可用。如果你在问题中包含了编译时得到的完整警告,那么它应该包含那些函数的隐式声明。如果没有原型,编译器会假设它们返回
int
的,而返回一个指针最终会导致未定义的行为表现为segfault。调整你的源代码,第一行是
字符串
并且它应该如预期的那样工作。