Разрешено ли использование const_cast для доступа только для чтения к объекту const?

StackOverflow https://stackoverflow.com/questions/1542200

Вопрос

В 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;
}

и мне нужно вызвать его для массива const:

static const int Array[] = { 10, 20, 0, 2};

countZeroes( const_cast<int*>( Array ), sizeof( Array ) / sizeof( Array[0] ) );

будет ли это неопределенным поведением?Если да, то когда программа запустится в UB - при выполнении const_cast и вызове функции или при обращении к массиву?

Это было полезно?

Решение

Да, это разрешено (если опасно!).Это фактическая запись в const объект, который вызывает неопределенное поведение, а не само приведение (7.1.5.1 /4 [dcl.type.cv]).

Как указано в стандарте 5.2.11 / 7 [expr.const.cast], в зависимости от типа объекта попытка записи через указатель, который является результатом удаления const может приводить к неопределенному поведению.

Другие советы

Поскольку ваш код не изменяет массив, и вы сообщили компилятору, что знаете, что делаете, используя const_cast, с тобой действительно все будет в порядке.Однако я полагаю, что технически вы вызываете неопределенное поведение.Лучше всего исправить объявление функции или написать, объявить и использовать ее постоянную версию.

Да, вы можете это сделать.Нет, это не неопределенное поведение до тех пор, пока функция действительно не попытается выполнить запись в массив.

Проблема в const_cast всегда одно и то же - это позволяет вам "нарушать правила", точно так же, как кастинг туда и обратно void* -- конечно, ты можешь это сделать, но вопрос в том, зачем тебе это делать?

В данном случае это, конечно, нормально, но вы должны спросить себя, почему вы не объявили size_t countZeroes( const int* array, size_t count ) в первую очередь?

И , как общее правило , о const_cast:

  1. Это может привести к труднодоступным ошибкам
  2. Вы отбрасываете const-соглашение с компилятором
  3. По сути, вы переводите язык на более низкий уровень.

Используя const_cast на объекте, который изначально определен как const является UB, поэтому неопределенное поведение возникает непосредственно в точке, которую вы вызываете const_cast.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top