是否允许使用 const_cast 对 const 对象进行只读访问?

发布于 2024-08-07 00:27:00 字数 540 浏览 11 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

水中月 2024-08-14 00:27:00

是的,这是允许的(如果危险的话!)。实际写入 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.

情归归情 2024-08-14 00:27:00

由于您的代码不会修改数组,并且您通过使用 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.

初相遇 2024-08-14 00:27:00

是的,你可以这样做。不,只要函数确实不尝试写入数组,这就不是未定义的行为。

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.

£噩梦荏苒 2024-08-14 00:27:00

const_cast 的问题总是一样的——它允许你“打破规则”,就像在 void* 之间进行转换一样——当然你可以做到这一点,但问题是你为什么要这么做?

在这种情况下当然没问题,但您应该问自己为什么不首先声明 size_t countZeroes( const int* array, size_t count )

作为关于 const_cast 的一般规则:

  1. 它可能会产生很难发现的错误
  2. 你正在抛弃与编译器的 const 协议
  3. 基本上你正在将语言变成较低级别的语言。

The problem of const_cast is always the same -- it allows you to "break the rules", just like casting to and from void* -- 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:

  1. It may produce hard to find bugs
  2. You're throwing away the const-agreement with the compiler
  3. Basically you're turning the language into a lower-level one.
久光 2024-08-14 00:27:00

在最初定义为 const 的对象上使用 const_cast 是 UB,因此在调用 const_cast 时会立即出现未定义的行为。

Using const_cast on an object which is initially defined as const is UB, therefore the undefined behaviour comes about immediately at the point you call const_cast.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文