__ атрибут __ ((const)) vs __attribute __ ((чистый)) в GNU C

В чем разница между __attribute__((const)) и __attribute__((pure)) в GNU C?

__attribute__((const)) int f() {
    /* ... */
    return 4;
}

против

__attribute__((pure)) int f() {
    /* ... */
    return 4;
}

Ответ 1

В документации для компилятора ARM (который основан на gcc):

__attribute__((pure)) атрибут функции
Многие функции не имеют никаких эффектов, кроме как вернуть значение, а их возвращаемое значение зависит только от параметров и глобальных переменных. Функции такого рода могут быть подвергнуты анализу потока данных и могут быть устранены.

__attribute__((const)) атрибут функции
Многие функции проверяют только переданные им аргументы и не имеют никаких эффектов, кроме возвращаемого значения. Это гораздо более строгий класс, чем __attribute__((pure)), потому что функции не разрешено читать глобальную память. Если функция, как известно, работает только с ее аргументами, то она может быть подвергнута общему исключению суб-экспрессии и оптимизации цикла.

Итак, TL; DR: __attribute__((const)) совпадает с __attribute__((pure)), но без какого-либо доступа к глобальным переменным.

Ответ 2

Разница объясняется в руководствах GCC. В частности, const функция может использовать только передаваемые аргументы, а не какую-либо память, тогда как pure функция может также обращаться к памяти при ограничениях:

Атрибут pure запрещает функции изменять состояние программы, которое можно наблюдать, не проверяя возвращаемое значение функции. Однако функции, объявленные с атрибутом pure, могут безопасно читать любые энергонезависимые объекты и изменять значение объектов таким образом, чтобы это не влияло на их возвращаемое значение или наблюдаемое состояние программы.

__attribute__ ((pure)) означает, что функция не имеет побочных эффектов, а возвращаемое значение зависит от аргументов и состояния глобальных переменных. Поэтому для оптимизатора безопасно исключить некоторые вызовы, если аргументы совпадают, и вызывающая сторона не сделала ничего, чтобы изменить состояние глобалов между вызовами.

__attribute__ ((const)) означает, что возвращаемое значение является исключительно функцией аргументов, и если любой из аргументов является указателем, то указатели не должны быть разыменованы.

Функция const всегда pure.

Примерами const функций могут быть функции abs из <stdlib.h> и некоторые математические функции из <math.h>: sqrt, exp и т.д. (Хотя они могут подвергаться режимам округления).

Примерами pure но неконстантных функций могут быть такие функции, как strlen - поскольку он разыменовывает указатель, переданный в.

Ответ 3

Кто-нибудь знает, почему эти атрибуты не работают в gcc 7?

Ответ 4

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

Вы можете вернуть несколько значений в C, используя структуру, которая упрощает использование pure. (Более типично использовать операнды возврата указателя, но это нарушает использование pure).