2016-11-30 5 views
3

Я пытаюсь устранить все броски C-стиля в кодовой базе, из-за предупреждений стиля cppcheck cstyleCast.Всегда ли безопасно менять приведение в стиле C к static_cast?

Всегда ли безопасно менять листинг типа C на static_cast?

Безопасно, я имею в виду, существует ли ситуация, когда старое приведение в стиле C будет работать нормально, но static_cast может вызвать ошибку или неопределенное поведение?

type1 a; 
type2 b = (type2)a;    // C style cast 
type2 b = static_cast<type2>(a); // Is this always a valid replacement for above cast? 
+3

C cast может быть 'const_cast', но в этом случае вы будете иметь ошибку времени компиляции с' static_cast'. – Jarod42

ответ

6

C-стиль литья, как правило, комбо static_cast<> или reinterpret_cast<> с const_cast<>. Возможно, ошибки компиляции могут быть заменены только static_cast<>.

Мне не известны случаи, связанные с ошибками во время выполнения.

Вы можете начать использовать с static_cast<>, а затем добавить (или заменить его) const_cast<>, где возникают ошибки во время компиляции. Если после этого у вас все еще есть ошибки времени компиляции, необходимы reinterpret_cast<>. Но не делайте замену слепо - некоторые из этих случаев могут быть ошибками. Например, reinterpret_cast<> может потребоваться, если тип данных объявлен, но не определен, что приводит к неопределенному поведению (и, безусловно, вызовет проблемы, если задействовано несколько наследований).

Поиск таких ошибок является причиной того, что это упражнение повышает безопасность исходного кода и почему статический анализатор кода содержит флаги C-style casts.

2

C-style cast и static_cast не являются эквивалентными.

Есть ли ситуация, когда старое приведение в стиле C будет работать нормально, но static_cast может вызвать ошибку или неопределенное поведение?

В качестве примера:

int main() { 
    using FI = int(*)(); 
    using FV = void(*)(); 
    FI fi = nullptr; 
    FV fv = (FV)fi; 
    //FV fv2 = static_cast<FV>(fi); 
} 

Если вы раскомментировать строку, которая использует static_cast, код не компилируется.
В качестве примечания, в данном случае, вы должны использовать reinterpret_cast.

+1

Если код не компилируется. Тогда это безопасно (поскольку у вас нет ошибок, введенных в ваш код). Вы объединяете безопасные и действенные, которые представляют собой разные концепции. –

+1

@LokiAstari Не совсем. OP попросил случай, в котором 'static_cast' поднимет ошибку, и кастинг C-стиля будет работать (цитируется). В ответе есть такой случай. Я не сказал, что это действительно или безопасно, я опубликовал только пример, который отражает то, что просит ОП. Это все. Честно говоря, я не понял, что он имеет в виду. Вероятно, UB будет небезопасным, но ошибка достаточно безопасна, вы можете исправить ее до релиза. – skypjack

Смежные вопросы