代码之家  ›  专栏  ›  技术社区  ›  sharptooth

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

  •  5
  • sharptooth  · 技术社区  · 15 年前

    在C++中,我有一个函数,它只需要对数组进行只读访问,但错误地声明为接收非const指针:

    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和调用函数时,还是在访问数组时?

    5 回复  |  直到 15 年前
        1
  •  13
  •   CB Bailey    15 年前

    是的,允许(如果危险!)。这是给 const 引发未定义行为的对象,而不是强制转换本身(7.1.5.1/4[dcl.type.cv])。

    如5.2.11/7[expr.const.cast]中的标准注释所示,根据对象的类型,尝试通过一个指针进行写入,该指针是转换的结果。 康斯特 可能会产生不明确的行为。

        2
  •  1
  •   Jonathan Leffler    15 年前

    因为您的代码不修改数组,并且您告诉编译器您使用 const_cast 你会没事的。不过,我相信从技术上讲,您是在调用未定义的行为。最好修复函数声明,或者编写、声明和使用它的const-safe版本。

        3
  •  1
  •   Zanson    15 年前

    是的,你能做到。不,只要函数不试图写入数组,它就不是未定义的行为。

        4
  •  1
  •   Kornel Kisielewicz    15 年前

    问题 const_cast 总是一样的——它允许你“打破规则”,就像是从和向之间施法一样。 void* --当然可以,但问题是你为什么要这样做?

    在这种情况下,当然可以,但你应该问问自己为什么不申报 size_t countZeroes( const int* array, size_t count ) 首先?

    一般来说 康斯特卡斯特 :

    1. 可能会产生难以发现的错误
    2. 你在放弃与编译器的常量协议
    3. 基本上你是在把语言变成一种低级语言。
        5
  •  -2
  •   1800 INFORMATION    15 年前

    使用 const_cast 在最初定义为 const 是ub,因此未定义的行为会在您调用时立即发生。 康斯特卡斯特 .