2010-05-05 2 views
18

Насколько я понимаю, GCC поддерживает все свои функции C99 на C++. Но как строгое сглаживание C99 обрабатывается в коде C++?C99 строгие правила псевдонимов в C++ (GCC)

Я знаю, что кастинг с C-трансляциями между несвязанными типами не является строгим сглаживанием и может генерировать неправильный код, но как насчет C++? Поскольку строгое наложение не является частью стандарта C++ (верно ли это?), GCC должен указать саму семантику.

Я фигурирую const_cast и static_cast между родственными типами, следовательно, они безопасны, а reinterpret_cast могут нарушать строгие правила псевдонимов.

Это правильное понимание?

ответ

31

Нет, вы, вероятно, смешиваете разные вещи.

Строгие правила сглаживания не имеют абсолютно никакого отношения к стандарту C99. Строгие правила сглаживания внедрены в части стандарта, которые присутствовали на C и C++ с начала [стандартизованных] раз. Статья, запрещающая доступ к объекту одного типа через lvalue другого типа, присутствует в C89/90 (, 6.3), а также в C++ 98 (3.10/15). Вот что такое строгий алиасинг, не больше, не меньше. Дело в том, что не все компиляторы хотели (или осмелились) использовать его или полагаться на него. Как языки C, так и C++ иногда используются в качестве «высокоуровневых сборочных» языков, а правила строгого сглаживания часто мешают подобным применениям. Именно GCC сделал этот смелый шаг и решил начать полагаться на строгие правила псевдонимов в оптимизации, часто вызывая жалобы от этих «сборочных» типов.

Это правда, что самый простой способ нарушить строгие правила псевдонимов на C++ - это reinterpret_cast (и, конечно же, C-стиль). Однако static_cast также может быть использован для этой цели, так как она позволяет нарушить строгие ступенчатости с помощью void * в качестве промежуточного типа в «приковано» слепке

int *pi; 
... 
double *pd = static_cast<double *>(static_cast<void *>(pi)); 

const_cast не может нарушить строгие ступенчатости в совместимом компилятор.

Что касается C99 ... Что C99 представил, то был классификатор restrict. Это напрямую связано с псевдонимом, но это не то, что известно как строгое сглаживание как таковое.

+1

Вы правы, я думал о C99 'ограничивать 'ключевое слово, а не строгий псевдоним. По какой-то причине он укоренился в моем сознании таким образом («C99» + «строгий псевдоним»). –

+0

Так что же такое предмет, о котором идет речь?Означает ли это, что любой код C89/C99/C++ 98, который нарушает строгие правила псевдонимов, является технически некорректным (запрет на компилятор-специфические ключи, такие как -fno-strict-aliasing)? –

+0

@Checkers: Я добавил номера в свой ответ. И да, код, который нарушает строгие правила псевдонижения, демонстрирует неопределенное поведение на C89 и на C++ 98. – AnT

4

static_cast также может нарушать правила псевдонимов, поскольку компилятор доверяет вам, чтобы целевой тип был связан с фактическим типом времени выполнения объекта. Рассмотрим:

extern void f(double*, int*); // compiler may optimize assuming that arguments don't overlap 
double d; 
void* pv = &d; 
int* pi = static_cast<int*>(pv); 
f(&d, pi); // assumption is violated 
2

Концепция такая же в Cpp; в том, что вы можете использовать приведения стиля C, чтобы вести вас через то, что считается безопасным по строгому сглаживанию.

Вкратце: нет, подход к использованию каста Cpp (который вы наметили) не будет безопасно охватывать все случаи. Одним из распространенных способов нарушения правил является использование static_cast для указания указателей.

Просто включите предупреждения компилятора - он будет (или, должен) рассказать вам, что небезопасно.

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