考虑到fopen()失败,在以下代码中:
FILE *fp = fopen("file.txt", "w");
if (fp == NULL) {
printf("Error occurred while opening file, errno=%d, %s\n",
errno, strerror(errno));
exit(1);
}由于函数参数的计算顺序在C中未指定,因此在调用printf()时,如果首先对strerror()的调用(调用)而失败,那么在实际打印行时,errno 被设定是否会对其他东西进行计算呢?或者,errno甚至在评估strerror()之前就会被复制到printf()的激活记录中,从而保持不变吗?这是不明确的行为吗?
编辑:是的,我知道我可以在fopen()之后将errno保存到一些int,但这不是我的重点。我试图弄清楚上面的代码是如何运行的。
发布于 2022-07-29 13:05:53
由于没有保留返回值来指示错误,希望检查错误情况的应用程序应该将errno设置为0,然后调用strerror(),然后检查errno。
你用过的同一篇文章。很可能是没有具体说明的行为。人也是这样说的
POSIX.1-2001和POSIX.1-2008要求对strerror()或strerror_l()的成功调用保持errno不变,并注意,由于没有保留函数返回值来指示错误,希望检查错误的应用程序应该在调用之前将errno初始化为零,然后在调用后检查errno。
这样您就可以保存errno of fopen,然后得到errno of strerror。或者简单地使用perror。
发布于 2022-07-29 17:29:54
考虑到
fopen失败,在以下代码中: 文件*fp = fopen("file.txt","w");if (fp == NULL) {printf(“打开文件时发生错误,errno=%d,%s\n",errno,strerror(errno));退出(1);} 由于函数参数的计算顺序在C中未指定,因此在调用printf时,如果首先对strerror的调用(调用)失败,那么当实际打印行时,errno是否会被设置为其他东西?
这确实是可能的。此外,根据C标准,可以将errno设置为非零值,无论对strerror或任何其他库函数的调用是否有错误,只要函数没有记录errno的使用情况(参见C17 7.5/3)。但是,POSIX (自POSIX1.2001,以及1997年单一UNIX规范中的版本2)保证,如果成功,strerror不会更改errno的设置。
或者,
errno甚至在评估strerrno()之前就会被复制到printf的激活记录中,从而保持不变吗?这是不明确的行为吗?
这是没有具体说明的行为。参数和函数指示符可以按任何顺序计算(但在实际调用函数之前有一个序列点,以避免函数主体内的计算与另一个函数体内的计算相互交织)(请参阅C17 6.5.2.2/10)。
发布于 2022-09-24 11:23:35
这是一个在Linux下可能发生的问题,正如手册 of strerror()在NOTES部分中所说的,errno可以通过服务进行修改:
POSIX.1-2001允许strerror()在调用遇到错误时设置errno,但没有指定函数在发生错误时返回的值。在某些系统上,如果错误号未知,strerror()将返回NULL。在其他系统上,strerror()返回一个字符串,类似于"Error已发生“,如果错误号未知,则将errno设置为EINVAL。C99和POSIX1.2008要求返回值为非空值。
https://stackoverflow.com/questions/73167084
复制相似问题