示例代码如下:
void testFuncErrno()
{
fstream fstr;
fstr.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
fstr.open("/mnt/virtualfs/test.ss", ofstream::out);
fstr << "test" << endl;
}
catch(std::ifstream::failure e)
{
cout << "func catch errno is:" << errno << ":" << strerror(errno) << endl;
cout << "good?" << (fstr.good()?"yes":"no") << endl;
}
}
int main(int argc, char *argv[])
{
try
{
errno = 0;
testFuncErrno();
cout << "0 st errno is:" << errno << ":" << strerror(errno) << endl;
}
catch(std::ifstream::failure e)
{
cout << "catch errno is:" << errno << ":" << strerror(errno) << endl;
}
pause();
return 0;
}
当磁盘已满时,我想捕获errno,但是当函数结束时,似乎errno将被设置为零。我使用ddd来跟踪源代码,并在下面找到了一些注释,但是来自errno描述:
在程序启动时将errno设置为零,并且标准C库的任何函数都可以将其值修改为不等于零的某个值,通常用于指示特定类型的错误(没有库函数将其值设置回零一旦改变。)
这让我有点困惑,为什么关闭会将errno设置为零?
__basic_file<char>*
__basic_file<char>::close()
{
__basic_file* __ret = static_cast<__basic_file*>(NULL);
if (this->is_open())
{
int __err = 0;
if (_M_cfile_created)
{
**// In general, no need to zero errno in advance if checking
// for error first. However, C89/C99 (at variance with IEEE
// 1003.1, f.i.) do not mandate that fclose must set errno
// upon error.**
errno = 0;
do
__err = fclose(_M_cfile);
while (__err && errno == EINTR);
}
_M_cfile = 0;
if (!__err)
__ret = this;
}
return __ret;
}
答案 0 :(得分:0)
在调用已知设置errno的库函数之前将errno设置为零是一个好习惯,并且只有在函数返回指示失败的值之后才检查errno。这是因为无论是否存在错误,都可以通过C标准库函数调用将errno的值设置为非零,前提是函数描述中未记录errno的使用。
因此,如果仅在程序开始时初始化errno,则无法保证错误值是由哪个函数调用设置的。
在调用fclose()之前将错误设置为0确认errno所具有的值是由fclose()设置的,而不是其他函数。
您可以在下面找到有关使用的讨论: https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=6619179