C99 строгие правила псевдонимов в С++ (GCC)

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

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

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

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

Ответ 1

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

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

Правда, самый простой способ нарушить строгие правила псевдонимов на С++ - это reinterpret_cast (и, конечно, C-стиль). Тем не менее, static_cast также может использоваться для этой цели, поскольку он позволяет нарушать строгий псевдоним, используя void * в качестве промежуточного типа в "прикованном" литье

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

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

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

Ответ 2

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

Ответ 3

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

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

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