是运行时糟糕的C风格铸件定义的行为
Is the behaviour for a runtime bad C-style cast defined?
如果您将旧的c风格从A型到类型B进行旧的C型铸件,则C 标准是否会定义特定的行为,而A型A类型A类型不能铸造为B型,反之亦然?
是否存在一种已知的可见行为,可以假定使用此操作时在运行时造成非法铸造的症状?
只有四个C - 样式铸件中的一个确定铸件在运行时的有效性,即dynamic_cast
。
c风格的铸件对应于其他三个铸件的组合(static_cast
,reinterpret_cast
,const_cast
)。这些铸件的有效性是在编译时确定的,或者如果无法在编译时间确定,则假定铸件是有效的。C风格的演员永远不会像dynamic_cast
一样。
因此,在运行时"失败"的C风格铸件,即打破有效性假设,会导致不确定的行为。所以:
如果您将旧的C风格从A型到B型铸造,则C 标准是否会定义特定的行为,其中A型A类型不能铸造为B型,反之亦然?
no。
是否会有一种已知的可见行为可以假定是在运行时造成非法演员的症状?
no。
编译器会捕获其中的一些,但不是全部。这是灾难性演员的示例:
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(std::string s, int x) : m_s(s), m_x(x) {}
void print() { cout << "A::print(): str = " << m_s << ", x = " << m_x << endl; }
private:
std::string m_s;
int m_x;
};
class B {
public:
B(int x) : m_x(x) {}
void print() { m_x++; cout << "B::print(): x = " << m_x << endl; }
private:
int m_x;
};
int main(int argc, char **argv) {
A *a = new A("abc", 1);
a->print();
B *b = (B*)a;
b->print();
a->print();
return 0;
}
在GCC上结果(Ubuntu 5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609:
A::print(): str = abc, x = 1
B::print(): x = 24828977
A::print(): str = bc, x = 1
是的,我们在A数据的数据上称为B的方法,这意味着我们的C风格铸件作为reinterpret_cast
。reinterpret_cast
仅采用一个内存区域,允许您对待是不同的东西。这里没有安全带。
另一方面,如果您尝试编译类似的内容
A a;
B b;
a = (A)b;
return 0;
它将导致static_cast
和编译时错误。因此,C风格的铸造结果取决于上下文。
处理模板和auto
时,这是噩梦。
要避免此问题,请使用static_cast
(用于编译时间检查)和dynamic_cast
(用于运行时检查)或reinterpret_cast
(用于指针和POD),清楚地说明了您的意图。
- 我可以在运行时重新定义在 OpenCascade/OCCT 标头中定义的 c++ 静态常量吗?
- 如何在 Visual Studio C++ 11 中运行时定义二维数组?
- 是否可以在运行时调用用于选择要调用的用户定义文本的逻辑?
- 在运行时使用用户定义的文本
- C++如何在运行时定义类?
- 是否有任何可能的方法将事件(自定义)附加到在运行时创建的对象?[C 构建器]
- 自定义char*插入功能多次运行时会产生运行时错误
- 上限time_point到运行时定义的持续时间
- 使用未定义符号的运行时错误:_ZN5boost6system15system_categoryEv
- 在运行时重新定义 c++ 中的 #define
- 是运行时糟糕的C风格铸件定义的行为
- 有条件地定义在运行时,在C 代码的其余部分中将使用3类
- 在运行时添加自定义Qwidget
- 定义大小 (n*m) 的 2d 数组时运行时错误 >=10^6
- 如何使用在运行时定义的数学函数创建类
- 是否可以在运行时定义要在STXXL中排序的类型的长度
- C++ XCode 中的错误:在定义运算符 * 时"no viable overloaded operator *=" *= 已经过测试并且正常运行
- 带有C++插件的节点应用程序在运行时抱怨未定义的符号
- 使用帮助程序函数 (c++) 定义运行时已知的全局 const 变量
- 如何在c++中定义运行时异常