для того, что я вижу, похоже, что restrict
учитывается только в том случае, если указано в аргументах функции
Эта характеристика звучит так, как вы думаете, restrict
квалификация несет в себе какую-то обязательство оптимизировать более агрессивно. Это явно не так:
Переводчик вправе игнорировать любые или все намеки на последствия использования restrict.
(C стандарт, пункт 6.7. 3.1 / 6)
Я допускаю, что немного удивительно, что компилятор, который использует квалификацию restrict
для выполнения дополнительных оптимизаций в некоторых случаях, не будет делать то же самое в других, подобных случаях, но это не означает, что ни код, ни компилятор никоим образом не правы. (Но имейте в виду замечание Эри c о членах структуры с ограниченным доступом). Кроме того, однако, представленные примеры могут не быть такими же похожими друг на друга, как вы предполагаете.
Является ли мое использование restrict неправильным, или gcc / clang реализует ограничение только для аргументов функции и ничего больше?
Несмотря на то, что стандарт определяет семантику для restrict
-квалифицированных переменных в области блока, они не могут быть использованы для многих. Ограниченная квалификация - это средство передачи некоторой ответственности за анализ зависимостей от компилятора к программисту, но у программиста нет больше информации, которую можно было бы применить, чем у компилятора в случае, таком как пример foo_restricted_cast()
. Я бы сказал, что да, ваше использование там (семантически) неверно, потому что у вас нет надежной основы для неявной гарантии того, что локальные переменные a
и b
не будут псевдонимами друг друга. Я оцениваю поведение G CC и Кланга в этом свете благоразумно и уместно, а я CC немного ra sh.
Что касается restrict
-квалифицированных членов структуры, я не согласен с утверждение другого ответа, что семантика для них не определена. Это правда, что идентификаторы членов структуры не являются «обычными идентификаторами», но формулировка определения семантики restrict
в стандарте, по-видимому, специально разработана с целью охвата элементов структуры через объявления обычных идентификаторов объектов структуры. содержащие их. Язык, безусловно, может быть прочитан таким образом, и это более чем обычно чревато, если подразумевается иначе.
Таким образом, я думаю, что случай foo_restricted_struct()
имеет четко определенную семантику и, кроме того, icc
оправдано использование преимуществ сглаживания, передаваемых квалификацией restrict
членов структуры аргумента, так же, как если бы они были прямыми параметрами функции. Я не могу сказать, почему gcc
и Clang
также не используют преимущества опций оптимизации, но опять же, они не обязаны это делать.
С другой стороны, foo_restricted_subcall()
демонстрирует семантическую c проблему, аналогичную проблеме в foo_restricted_cast()
. Я полагаю, что есть внешняя вероятность, что именно по этой причине G CC и / или Clang избегают более агрессивной оптимизации foo_restricted_struct()
, которую foo_restricted_subcall()
вызывает с семантически проблемным аргументом c. Однако, вероятно, эти компиляторы просто не выполняют достаточно глубокий анализ, чтобы увидеть возможность оптимизации в этом случае.