C++中const指针指向字面值是否有效?

4

我知道lvalues可以被转换成const引用。我想知道是否可以获得指向这些lvalues的指针。

如果我写

const int* p = &3; //ERROR: lvalue required as unary operand '&'

我收到了这个错误。然而,
const int* p = &((const int&)3);

这个编译是成功的。在这种情况下,*p的结果是否保证为3?


2
长话短说 - C风格的强制类型转换几乎总是意味着最好的情况下是实现定义行为,最坏的情况下是未定义行为。 - Richard Hodges
但是这也应该可以通过 static_cast<const int&>(3) 进行编译。 - eivour
它确实可以,但仍然是未定义行为。static_cast只能用于将类型强制转换回原始类型。 - Richard Hodges
4
@RichardHodges那是无稽之谈。static_cast可以在不同类型的一对一之间执行各种强制类型转换,包括 static_cast<const int&>(3)这个例子本身就是完全合法的。UB的产生是因为在对象的生命周期结束后尝试使用它,而不是通过强制类型转换创建该对象产生的。 - Igor Tandetnik
@IgorTandetnik 你是对的。它可以执行合法转换。我把 static_cast 和 reinterpret_cast 混淆了。 - Richard Hodges
1个回答

8

这样会构造一个临时的 int(3) 并将其绑定到const引用上。 p 的指针被指向该临时对象。 临时对象的生命周期被延长以与该引用相匹配 - 但是该引用本身是一个临时对象,并在分号处被销毁,导致 p 成为悬空指针。 任何尝试在此之后使用 p (除了对其赋新值)都会表现出未定义的行为。


1
同意-演示在此处:https://godbolt.org/g/5nKT49-`fooint`被调用时没有传入3个参数,而是零个。 - Richard Hodges
但这是合法的,对吧?const int& p = (const int&)3; const int* q = &p; 可能值得一提。 - AndyG
2
@AndyG 是的,我相信这是合法的。这只是常规的临时生命周期延长。不需要转换,可以直接写 const int& p = 3; - Igor Tandetnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接