Конечно, вы можете обнаружить чистые функции в некоторых случаях.Например,
int f(int x)
{
return x*2;
}
можно определить как чистый с помощью простого статического анализа.Сложность заключается в том, чтобы сделать это в целом, и обнаружить интерфейсы, которые используют «внутреннее» состояние, но внешне чистые, в принципе невозможно.
GCC имеет опции предупреждений -Wsuggest-attribute=pure
и -Wsuggest-attribute=const
, которые предлагают функции, которые могут быть кандидатами для атрибутов pure
и const
.Я не уверен, предпочитает ли он быть консервативным (то есть пропускает много чистых функций, но никогда не предлагает его для не чистой функции) или позволяет пользователю решать.
Обратите внимание, что определение pure
в GCC«зависит только от аргументов и глобальных переменных»:
Многие функции не имеют эффектов, кроме возвращаемого значения, и их возвращаемое значение зависит только от параметров и / или глобальных переменных.Такая функция может быть подвержена общему исключению подвыражения и оптимизации цикла, как если бы был арифметический оператор.Эти функции должны быть объявлены с атрибутом pure
.
- GCC manual
Строгая чистота, то есть одинаковые результаты для одинаковых аргументов при любых обстоятельствах, представлен атрибутом const
, но такая функция не может даже разыменовать переданный ему указатель.Таким образом, возможности распараллеливания для pure
функций ограничены, но гораздо меньше функций может быть const
по сравнению с чистыми функциями, которые вы можете написать на языке, подобном Haskell.
Кстати, автоматическое распараллеливание чистых функцийне так просто, как вы думаете;трудная часть принимает решение что распараллелить.Распараллеливать вычисления, которые слишком дешевы, а накладные расходы делают это бессмысленным.Не распараллеливайтесь достаточно, и вы не пожнете выгоды.Я не знаю ни одной практической реализации функционального языка, которая бы делала автоматическое распараллеливание по этой причине, хотя такие библиотеки, как repa , распараллеливают многие операции за кулисами без явного параллелизма в пользовательском коде.