C99 строгие правила псевдонимов в C ++ (GCC) - PullRequest
18 голосов
/ 05 мая 2010

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

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

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

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

Ответы [ 3 ]

31 голосов
/ 05 мая 2010

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

Строгие правила псевдонимов не имеют абсолютно никакого отношения к стандарту 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. Это напрямую связано с псевдонимами, но это не так называемый строгий псевдоним как таковой.

4 голосов
/ 05 мая 2010

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 голосов
/ 05 мая 2010

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

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

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

...