c++异常处理的一件非常奇怪的事

functexcept中有一个函数__throw_out_of_range 只有声明,找不到它的定义
而且特别奇怪

 #include <iostream>
#include <typeinfo>

using namespace std;

int main()
{
    try
    {
        __throw_out_of_range("out_of_range");
    }
    catch(out_of_range &err)
    {
        cout<<typeid(err).name()<<endl;
    }
    return 0;
}

我这样写的话,当然会编译错误,因为没#include <stdexcept>
会得到[Error] 'out_of_range' does not name a type
因为out_of_range是在stdexcept中定义的一个类,也就是我的程序中没有它的定义
但是

 #include <iostream>
#include <typeinfo>

using namespace std;

int main()
{
    try
    {
        __throw_out_of_range("out_of_range");
    }
    catch(exception &err)
    {
        cout<<typeid(err).name()<<endl;
    }
    return 0;
}

我这样的话会输出St12out_of_range
也就是我确实是捕获到它了,所以很奇怪,怎么能捕获到一个没有声明过的对象呢
__throw_out_of_range这个函数太奇怪了

C++文件是分别编译的,最后链接成整体程序。所以想要实现这种效果很容易啊,只需要在定义__throw_out_of_range的地方包含 stdexcept就可以了。


这里给你个例子:

 // my_throw.hh

 #ifndef _MY_THROW_HH_
 #define _MY_THROW_HH_

 void my_throw(const char* info);

 #endif
 // my_throw.cc

 #include <stdexcept>
 #include "my_throw.hh"

 void my_throw(const char* info)
 {
     throw std::out_of_range(info);
}
 //main.cc

#include <iostream>
#include <typeinfo>
#include "my_throw.hh"

using namespace std;

int main()
{
    try
    {
        my_throw("out_of_range");
    }
    catch(exception &err)
    {
        cout<<typeid(err).name()<<endl;
    }
    return 0;
}

你可以跑跑这段代码试试,应该也是正常的,而且main.cc里面(即使包含了my_thorw头文件)见不到std::out_of_range的定义或者声明。
这里__throw_out_of_range可能已经编译器内置了,连包含都不需要

PS:
既然__throw_out_of_range是以两个下划线开始的,就暗示了你不该在自己的程序里使用这个函数 ... ...

 // ISO 9899:2011

 Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

— All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

catch语句内程序有错误。

那个应该算宏指令,你查看下宏定义