В чем разница между __attribute__((const))
и __attribute__((pure))
в GNU C?
__attribute__((const)) int f() {
/* ... */
return 4;
}
против
__attribute__((pure)) int f() {
/* ... */
return 4;
}
В чем разница между __attribute__((const))
и __attribute__((pure))
в GNU C?
__attribute__((const)) int f() {
/* ... */
return 4;
}
против
__attribute__((pure)) int f() {
/* ... */
return 4;
}
В документации для компилятора ARM (который основан на gcc):
__attribute__((pure))
атрибут функции
Многие функции не имеют никаких эффектов, кроме как вернуть значение, а их возвращаемое значение зависит только от параметров и глобальных переменных. Функции такого рода могут быть подвергнуты анализу потока данных и могут быть устранены.
__attribute__((const))
атрибут функции
Многие функции проверяют только переданные им аргументы и не имеют никаких эффектов, кроме возвращаемого значения. Это гораздо более строгий класс, чем__attribute__((pure))
, потому что функции не разрешено читать глобальную память. Если функция, как известно, работает только с ее аргументами, то она может быть подвергнута общему исключению суб-экспрессии и оптимизации цикла.
Итак, TL; DR: __attribute__((const))
совпадает с __attribute__((pure))
, но без какого-либо доступа к глобальным переменным.
Разница объясняется в руководствах GCC. В частности, const
функция может использовать только передаваемые аргументы, а не какую-либо память, тогда как pure
функция может также обращаться к памяти при ограничениях:
Атрибут pure запрещает функции изменять состояние программы, которое можно наблюдать, не проверяя возвращаемое значение функции. Однако функции, объявленные с атрибутом pure, могут безопасно читать любые энергонезависимые объекты и изменять значение объектов таким образом, чтобы это не влияло на их возвращаемое значение или наблюдаемое состояние программы.
__attribute__ ((pure))
означает, что функция не имеет побочных эффектов, а возвращаемое значение зависит от аргументов и состояния глобальных переменных. Поэтому для оптимизатора безопасно исключить некоторые вызовы, если аргументы совпадают, и вызывающая сторона не сделала ничего, чтобы изменить состояние глобалов между вызовами.
__attribute__ ((const))
означает, что возвращаемое значение является исключительно функцией аргументов, и если любой из аргументов является указателем, то указатели не должны быть разыменованы.
Функция const
всегда pure
.
Примерами const
функций могут быть функции abs
из <stdlib.h>
и некоторые математические функции из <math.h>
: sqrt
, exp
и т.д. (Хотя они могут подвергаться режимам округления).
Примерами pure
но неконстантных функций могут быть такие функции, как strlen
- поскольку он разыменовывает указатель, переданный в.
Кто-нибудь знает, почему эти атрибуты не работают в gcc 7?
Обратите внимание, что если функции передается указатель и проверяется контекст этого указателя, она не может быть объявлена как const
, даже если переданный указатель и контексты указателя являются const
. Это серьезное ограничение полезности const
.
Вы можете вернуть несколько значений в C, используя структуру, которая упрощает использование pure
. (Более типично использовать операнды возврата указателя, но это нарушает использование pure
).