Применяются ли правила строгого алиасинга к вызовам функций? - PullRequest
0 голосов
/ 15 апреля 2019

В приведенном ниже примере в f1 псевдоним не возникает, поскольку p (void*) недоступен, а p1 - единственный указатель, обращающийся к памяти. Однако существует псевдоним указателя между p1 (float*) и p2 (int*), который находится за пределами f1.
Мой вопрос заключается в том, является ли этот псевдоним незаконным или нет, то есть правила строгого псевдонима применяются к вызовам функций?

Если этот пример действителен, что если f1 встроен?

void f1(void *p)
{
  auto* p1 = static_cast<float*>(p);
  *p1 = 1.f;
}

int f2()
{
  int x = 1;
  auto* p2 = &x;
  f1(&x);
  *p2 = 1;
  return *p2;
}

Ответы [ 2 ]

7 голосов
/ 15 апреля 2019

Неважно, сколько раз вы копируете указатель или передаете его куда-то еще, или сколько раз вы конвертируете его, определяющим фактором всегда является то, что на самом деле хранится в этом месте.

В вашем случае единственное, что имеет значение, это то, является ли аргумент static_cast адресом float, а это не так.

0 голосов
/ 12 мая 2019

Компиляторы, которые подходят для низкоуровневого программирования на платформах с опубликованным ABI, обеспечат средства для принудительного выполнения вызовов функций в соответствии с этим ABI, что, в свою очередь, приведет к "строгим нарушениям псевдонимов", которые пересекаютграница вызова функции должна обрабатываться «в задокументированной форме, характерной для окружающей среды».Такая поддержка является «популярным расширением», которое авторы Стандарта считают вне своей юрисдикции.Компиляторы, которые спроектированы и сконфигурированы так, чтобы они подходили для низкоуровневого программирования, будут поддерживать такие конструкции, независимо от того, требует ли Стандарт этого, и те, которые не предназначены и не приспособлены для таких целей, не должны использоваться для них.

...