了解 C4673 编译器警告
Posted
技术标签:
【中文标题】了解 C4673 编译器警告【英文标题】:Understanding C4673 compiler warning 【发布时间】:2015-07-22 11:50:42 【问题描述】:关于警告C4673 的 MSDN 文章包含此示例,该示例发出带有特定消息的警告:
Base: this base class is inaccessible
// C4673.cpp // compile with: /EHsc /W4 class Base private: char * m_chr; public: Base() m_chr = 0; ~Base() if(m_chr) delete m_chr; ; class Derv : private Base public: Derv() ~Derv() ; int main() try Derv D1; // delete previous line, uncomment the next line to resolve // Base D1; throw D1; // C4673 catch(...)
很遗憾,MSDN 文章没有对这个问题给出任何解释。我不明白上面的代码有什么问题。为什么会发出警告?
这是 MSVC 2013 - v120 工具集。
【问题讨论】:
看不到代码很难提供任何建议 @Petr:正如我所说,代码在 MSDN 文章中。我把它贴在这里。 那么我建议将您的问题改写为“我不明白...的示例”,并且根本不提及您的代码。 FWIW,我发现this SO Q&A 似乎表明此特定警告有时会在没有正当理由的情况下发出。同样 FWIW,我已向 MSDN 添加了反馈,即有关警告的文章没有帮助,因为它没有指出警告 关于 的内容。我假设这是特定于 MSVC 的异常处理机制的东西。 @Barry:catch
没关系,警告是在throw
站点生成的,似乎不受catch
的影响。
【参考方案1】:
我可以在webcompiler 上复制此内容,警告的全文是:
main.cpp(28): 警告 C4673: throwing '
Derv
' 在捕获站点将不考虑以下类型 main.cpp(28): 警告 C4670: 'Base
': 这个基类不可访问
确实如此。如果我们有:
try
throw Derv();
catch (Base& )
std::cout << "I caught it!";
该处理程序与Derv
异常不匹配,因为Derv
私下继承自Base
,因此无法访问基类。所以在这个例子中,异常不会被捕获。
但是,在 MSDN 示例中发出一个奇怪的警告,异常将被捕获:
catch(...)
因此,该警告似乎实际上并没有检查任何内容 - 它只是一个一般性警告,表明您可能正在做一些有害的事情,而没有实际检查您是否存在。这对我来说似乎不是一个特别有用的警告。如果我们被Base&
追赶,是的 - 告诉我这不会发生 - 但我们正在追赶...
。
【讨论】:
原来如此!私人继承!我没有注意到。将其更改为公开即可解决问题。 ...并在示例中添加catch( Base & )
,或者甚至省略catch( ... )
,都会清楚地说明警告的含义。另一个 MS 宝石...
警告catch (Base&)
是不正确的。假设有一个翻译单元包含 Base 的定义,但不包含 Derv。编译器不会知道 Derv 是从 Base 私有继承的,因此它无法发出警告。【参考方案2】:
这是一个更精简的例子:
class Base public: virtual ~Base() ;
class Derived : private Base ;
int main()
Derived d;
throw d; // C4673
这里的问题是,开发人员可能会编写像这样的throw
语句作为任何函数的一部分,然后期望生成的异常被多态地捕获为Base
。这不起作用,因为继承是private
。您必须抓住Derived
或...
。
此处适合使用警告的原因是您不只是throw
任何对象。通常,您有专门用于此目的的特定异常类型。对此类异常类型使用私有继承没有任何意义。它只会引入像这样令人困惑的行为,但没有真正的用例。
不幸的是,我们可以检测一个类是否是异常类型的唯一地方是throw
,所以这是我们可以生成此警告的唯一地方。
【讨论】:
以上是关于了解 C4673 编译器警告的主要内容,如果未能解决你的问题,请参考以下文章