这个一定要记录一下,软件总是运行到一定程度就自己退出了,弄的莫名其妙的,一开始以为是自己的代码写错了,但是定位错误位置永远在rename的位置退出,想着怎么也不会是c++函数的错,结果死磕了一个星期还是这句代码不对,然后就开始查这个函数,发现了问题。
c++在异常处理的时候使用的是noexcept
进行异常的抛出,这里noexcept
的用法以比较特殊
- noexcept:表示不抛出任何异常,但是如果一旦发生异常,则会调用
terminate()
,然后terminate()调用abort()
,直接终止程序 - noexcept():如果是带参数的则表示某些情况下不抛出异常,当表达式为true时不抛出异常,当表达式为false时则会抛出异常。
这里发现程序不抛出异常直接退出是因为在rename()
函数中,使用的是noexcept,也就是说定义为不抛出任何异常,如果发生异常时直接退出。
我这里一开始使用的是c的函数没弄明白后来换了c++11中的filesystem中的函数看明白了。
filesystem主要是关于系统操作的一系列内容,需要导入<filesystem>
,但是在使用的时候,他属于std::tr2::sys
命名空间,我尝试了好多中网上的调用,只有这一种是对的,另外还用一种是看完代码后发现的。
源码
namespace tr2 {
namespace sys {
using namespace _STD experimental::filesystem::v1; // retained
} // namespace sys
} // namespace tr2
第一种
std::tr2::sys
第二种
experimental::filesystem::v1
rename函数的源码
inline void rename(const path& _Oldpval, const path& _Newpval)
{ // rename _Oldpval as _Newpval
error_code _Code;
rename(_Oldpval, _Newpval, _Code);
if (_Code != error_code())
_THROW_NCEE(filesystem_error,
"rename(p1, p2): invalid arguments");
}
inline void rename(const path& _Oldpval, const path& _Newpval,
error_code& _Code) _NOEXCEPT
{ // rename _Oldpval as _Newpval
_Code = error_code();
if (!exists(_Oldpval))
{ // fail immediately without modifying the filesystem
_Code = make_error_code(errc::operation_not_permitted);
return;
}
if (exists(_Newpval))
{ // both exist; there can be only one
if (equivalent(_Oldpval, _Newpval, _Code) || _Code != error_code())
return; // successful no-op, or report equivalent() failure
if (!remove(_Newpval, _Code))
return; // report remove() failure
}
if (_Rename(_Oldpval.c_str(), _Newpval.c_str()) != 0)
_Code = make_error_code(errc::operation_not_permitted);
}
上面rename函数有两个重载,实际上调用的都是第二个函数,第二个函数有一个_NOEXCEPT
,这个就是noexcept
#if _HAS_EXCEPTIONS
#define _NOEXCEPT noexcept
#define _NOEXCEPT_OP(x) noexcept(x)
#else /* _HAS_EXCEPTIONS */
#define _NOEXCEPT throw ()
#define _NOEXCEPT_OP(x)
#endif /* _HAS_EXCEPTIONS */
上面的代码可以看到底层调用的还是c的函数reneme
,至于在c函数中如何定义异常我还没有弄明白,但是这里应该可以确定rename()
函数发生了异常并且没有进行抛出然后直接执行了终止程序,然后程序跳出了。