是否允许使用 const_cast 对 const 对象进行只读访问?
在 C++ 中,我有一个只需要对数组进行只读访问的函数,但被错误地声明为接收非常量指针:
size_t countZeroes( int* array, size_t count )
{
size_t result = 0;
for( size_t i = 0; i < count; i++ ) {
if( array[i] == 0 ) {
++result;
}
}
return result;
}
并且我需要为常量数组调用它:
static const int Array[] = { 10, 20, 0, 2};
countZeroes( const_cast<int*>( Array ), sizeof( Array ) / sizeof( Array[0] ) );
这会是未定义的行为吗?如果是这样 - 程序什么时候会运行到 UB - 当执行 const_cast 并调用函数时或访问数组时?
In C++ I have a function that only requires read-only access to an array but is mistakenly declared as receiving a non-const pointer:
size_t countZeroes( int* array, size_t count )
{
size_t result = 0;
for( size_t i = 0; i < count; i++ ) {
if( array[i] == 0 ) {
++result;
}
}
return result;
}
and I need to call it for a const array:
static const int Array[] = { 10, 20, 0, 2};
countZeroes( const_cast<int*>( Array ), sizeof( Array ) / sizeof( Array[0] ) );
will this be undefined behaviour? If so - when will the program run into UB - when doing the const_cast and calling the functon or when accessing the array?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,这是允许的(如果危险的话!)。实际写入
const
对象会导致未定义的行为,而不是强制转换本身 (7.1.5.1/4 [dcl.type.cv])。正如 5.2.11/7 [expr.const.cast] 中的标准所述,根据对象的类型,尝试通过作为抛弃
const
的结果的指针进行写入可能会产生 undefined行为。Yes, it is allowed (if dangerous!). It's the actual write to a
const
object that incurs undefined behaviour, not the cast itself (7.1.5.1/4 [dcl.type.cv]).As the standard notes in 5.2.11/7 [expr.const.cast], depending on the type of the object an attempt to write through a pointer that is the result of casting away
const
may produce undefined behaviour.由于您的代码不会修改数组,并且您通过使用 const_cast 告诉编译器您知道自己在做什么,所以实际上没问题。但是,我相信您在技术上调用了未定义的行为。最好修复函数声明,或者编写、声明并使用它的 const 安全版本。
Since your code does not modify the array, and you told the compiler you know what you are doing by using the
const_cast
, you will actually be OK. However, I believe you are technically invoking undefined behaviour. Best to get the function declaration fixed, or write, declare and use the const-safe version of it.是的,你可以这样做。不,只要函数确实不尝试写入数组,这就不是未定义的行为。
Yes, you can do that. No, it is not undefined behavior as long as the function truely does not try to write to the array.
const_cast
的问题总是一样的——它允许你“打破规则”,就像在void*
之间进行转换一样——当然你可以做到这一点,但问题是你为什么要这么做?在这种情况下当然没问题,但您应该问自己为什么不首先声明
size_t countZeroes( const int* array, size_t count )
?作为关于 const_cast 的一般规则:
The problem of
const_cast
is always the same -- it allows you to "break the rules", just like casting to and fromvoid*
-- sure you can do that, but the question is why should you?In this case it's of course ok, but you should ask yourself why didn't you declare
size_t countZeroes( const int* array, size_t count )
in the first place?And as a general rule about
const_cast
:在最初定义为 const 的对象上使用 const_cast 是 UB,因此在调用 const_cast 时会立即出现未定义的行为。
Using
const_cast
on an object which is initially defined asconst
is UB, therefore the undefined behaviour comes about immediately at the point you callconst_cast
.