Присвоение аргумента указателя с ограничением локальной переменной с ограничением

После прочтения стандарта C, 6.7.3.1 «Формальное определение restrict», у меня возникло следующее недоразумение. Интересно, следующий код мгновенно вызывает неопределенное поведение:

void foo(int *restrict p) {
  int *restrict q = p;
}

Понятно, что q присваивается значение, основанное на другом ограниченном указателе p. Неясно, связаны ли эти два указателя с одним и тем же блоком (самой функцией) или с разными блоками (p с самой функцией, q с телом составного оператора), потому что, например.

int *restrict p;
{
  int *restrict q = p;
}

не вызывает неопределенного поведения (можно создавать псевдонимы указателей в подблоках).

Верхний ответ в MSVC++ ограничивает ключевое слово и локальные переменные предполагает, что int *restrict q = p + 1; подойдет , однако [по крайней мере, в случае стандарта C] это неверно, потому что выражение p + 1 по-прежнему основано на p.

Определение блока находится в 6.7.3.1 p2:

  1. Если [объявление определенного указателя] D появляется внутри блока и не имеет класса хранения extern, пусть B обозначить блок. Если D появляется в списке объявлений параметров определения функции, пусть B обозначает соответствующий блок. [...]

Так является ли «связанный блок» функции тем же самым, что и тело функции в этом контексте? Потому что я не сразу нашел какое-либо объяснение термина «связанный блок» ранее в тексте.


person NoQ    schedule 29.01.2016    source источник
comment
6.7.3p8 даже не говорит об объявлениях в разных областях. Также было бы не очень интуитивно делать это зависящим от области видимости. После того, как вы назовете объект двумя указателями, ни один из них не должен быть квалифицирован restrict. внутри функции. Полагаться на что-то еще, кроме стандарта для таких деталей, вообще плохая идея. И, в частности, известно, что MS плохо следует стандарту C (они даже не поддерживают предыдущую версию стандарта, C99).   -  person too honest for this site    schedule 29.01.2016
comment
связанный блок wuite явно относится к блоку, связанному с ограничением. Обратите внимание, что вложенные блоки также являются частью окружающих их блоков. Также о UB, поиске связанного блока, J.2 может пролить свет на эту тему. Также см. 6.2.1p4   -  person too honest for this site    schedule 29.01.2016
comment
Насколько я понимаю, ключевое слово ограничения можно применять только к параметрам функции.   -  person fuz    schedule 29.01.2016
comment
@FUZxxl: я не вижу этого в стандарте. 6.7.3.1p7 показывает даже примеры в файловой области. И ограничение restrict параметрами функций кажется мне неразумным.   -  person too honest for this site    schedule 29.01.2016
comment
@ Олаф Хуч? Ух ты. Похоже, я заблуждался.   -  person fuz    schedule 29.01.2016
comment
@FUZxxl;: Может быть, потому, что они мало используются внутри функций (компилятор может сам анализировать программный поток), а глобальные переменные в любом случае часто не рекомендуются. Не забывайте, что классификатор по-прежнему используется редко.   -  person too honest for this site    schedule 29.01.2016
comment
@Olaf: Есть несколько мест, где квалификатор может использоваться внутри функций, особенно если переменная-указатель может быть загружена из любого из нескольких разных источников.   -  person supercat    schedule 11.07.2016
comment
@supercat: я думаю, что ясно сказал об этом в своем комментарии. Внутри одной единицы компиляции, а точнее одной функции, компилятор имеет полный контекст, поэтому может сам определить зависимости. Современные компиляторы делают это довольно давно по той простой причине, что restrict это C99 и (как я уже упоминал) редко используется (будь то лень или незнание как FUZxxI). Это не вредно для использования, но я сомневаюсь, есть ли какая-то польза, кроме потенциального получения предупреждения о нарушении (хотя я бы не стал полагаться на его получение). Все это не относится к внешнему интерфейсу.   -  person too honest for this site    schedule 12.07.2016
comment
@Olaf: Насколько я могу судить, большинство программистов хотели бы, чтобы компиляторы работали быстрее. В то время как компиляторы становятся все более изощренными в своих способностях делать выводы, такие возможности сопряжены со значительными потерями в скорости компиляции и языковой семантике. Позволить программисту рассказать компилятору то, что он в противном случае мог бы не знать, было бы лучше, чем требовать, чтобы компилятор тратил время на каждую сборку, пытаясь понять это.   -  person supercat    schedule 12.07.2016
comment
@supercat: Странно. Большинству программистов нравится использовать высокий уровень абстракции, который подразумевает, что компилятор должен самостоятельно определять оптимизацию. Если вы предпочитаете сообщать компилятору все, что он может знать или не знать, Ассемблер может быть предпочтительным языком. Что ж, я довольно помешан на контроле, когда дело доходит до программирования, но даже я предпочитаю язык с высоким уровнем абстракции. С LTO на самом деле еще меньше необходимости в restrict и т. д. restrict на самом деле является хаком из-за отсутствия стандартизированной передачи такой информации от компилятора к компоновщику автоматически.   -  person too honest for this site    schedule 12.07.2016
comment
@Olaf: Моя философия заключается в том, что программисты должны сообщать компиляторам то, что программист легко узнает, а компилятор может не знать, и пусть компилятор решает, что делать с этой информацией. Есть много случаев, когда даже очень слабые поведенческие гарантии в граничных случаях могут позволить писать код более эффективно, чем это было бы возможно в противном случае; низкоуровневый язык не должен заставлять программиста писать код для операций, которые не нужны в машинном коде, чтобы программа соответствовала требованиям.   -  person supercat    schedule 12.07.2016
comment
@supercat: Ну, я предпочитаю концентрироваться на проблеме, а не на компиляторе. Преждевременная оптимизация в любом случае считается плохой практикой проектирования.   -  person too honest for this site    schedule 12.07.2016
comment
Давайте продолжим обсуждение в чате.   -  person supercat    schedule 12.07.2016