Разрешено ли использование const_cast для доступа только для чтения к объекту const? - PullRequest
5 голосов
/ 09 октября 2009

В 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 и вызове функции или при доступе к массиву?

Ответы [ 5 ]

13 голосов
/ 09 октября 2009

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

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

1 голос
/ 19 декабря 2009

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

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

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

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

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

1 голос
/ 09 октября 2009

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

0 голосов
/ 09 октября 2009

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

...