为什么要编译:
class Bar {};
int main() {
Bar i;
Bar *b = &i;
typedef const Bar& type;
type t = type(b);
}
G ++(4.5,4.7快照),Comeau和MSVC都很高兴,但警告未使用的变量。
编译器认为它意味着什么?是UB吗?为什么不是错误?
我认为这应该是一个错误,因为我在没有解除引用或疯狂演员的情况下意外地将Bar*
变成了const Bar&
。我认为这一切都是完全安全的。
答案 0 :(得分:4)
C风格的演员依次尝试不同的C ++演员类型:
执行的转化
[C++11: 5.4/5]:
由
- a
const_cast
(5.2.11),- a
static_cast
(5.2.9),- a
static_cast
后跟const_cast
,- a
reinterpret_cast
(5.2.10)或- a
reinterpret_cast
后跟`const_cast
,可以使用显式类型转换的强制转换表示法执行。应用相同的语义限制和行为,但在以下情况下执行static_cast时,转换有效,即使基数也是如此class无法访问:
- [..]
然后遵循各种复杂的规则,我不能打扰详细解析。
你得到必要的警告,这是一个愚蠢的演员,但因为这是你所要求的是什么尝试。
与:比较:
class Bar {};
int main() {
Bar *b = 0;
typedef const Bar& type;
const type t = static_cast<type>(b);
}
// In function 'int main()':
// Line 6: error: invalid static_cast from type 'Bar*' to type 'const Bar&'
// compilation terminated due to -Wfatal-errors.
答案 1 :(得分:1)
因为你正在施展它。
class Bar {};
int main() {
Bar *b = 0;
typedef const Bar& type;
const type t = b;
(void)t;
}
上面的示例吐出下一个错误:
error: invalid initialization of reference of type 'type {aka const Bar&}' from expression of type 'Bar*'
答案 2 :(得分:0)
看来引用可以转换为指针。你的表达基本上是,
Bar & r = reinterpret_cast<Bar&>(b);
但是在这种明确的形式中,我得到两个警告:
warning: casting ‘Bar*’ to ‘Bar&’ does not dereference pointer [enabled by default]
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
但这似乎不是错误。