__attribute __ ((pure)) применяется к функции void - PullRequest
0 голосов
/ 07 июля 2019

У меня есть функция, которая берет два массива и записывает в третий массив результат функции pure (c_i = a_i / b_i):

inline
void    array_division      (ptrdiff_t nmemb,
                             double dest[static nmemb],
                             const double src1[static nmemb],
                             const double src2[static nmemb])
        __attribute__((nonnull, pure));

inline
void    array_division      (ptrdiff_t nmemb,
                             double dest[static nmemb],
                             const double src1[static nmemb],
                             const double src2[static nmemb])
{

        for (ptrdiff_t i = 0; i < nmemb; i++)
                dest[i] = src1[i] / src2[i];
}

GCC выдает ошибку, потому что это нене следует ожидать, что чистая функция вернет void.

A чистая функция - это функция, которая действует как функция своих параметров и значений, на которые указывают эти параметры;и если ни один из параметров, ни значения, на которые они указывают, не изменяются между двумя вызовами, они должны быть избыточными, и вызов может быть опущен, что соответствует тому же значению, которое было возвращено предыдущим вызовом.

Моя функцияследует всем этим правилам: если ни один из трех массивов не изменяется между двумя вызовами функций, вызов функции может быть полностью удален;и они оценивают одно и то же значение (которого нет, потому что оно void).

Прав ли я, полагая, что GCC должен разрешить такое использование __attibute__((pure))?

Должен ли я вернутьсяфиктивная return 0;, чтобы избежать жалоб GCC?

РЕДАКТИРОВАТЬ:

Состояние ошибки в GCC: __ атрибут __ ((чистый)) для работы с неконстантные указатели

Ответы [ 2 ]

3 голосов
/ 07 июля 2019

А почему return 0; работает ... Согласно https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute:

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

Но обратите внимание и на саму причину, по которой вы не можете вернуть void: это не имеет смысла . Вы бы отказались от возможности возврата значения, а вместе с ним и единственной законной цели чистой функции.

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

Это означает, например, что функции, отмеченной pure, запрещено устанавливать записи в том массиве, который вы передали. Я немного удивлен, что он вообще допускает неконстантные указатели, а тем более назначение через них.

Что касается того, что произойдет после того, как вы обманули GCC для разрешения изменений в такой функции, я не уверен. Это зависит от того, что GCC указал, что он будет делать в этом случае.

1 голос
/ 07 июля 2019

Ваша функция не соответствует правилам чистой функции. Текст, связанный с текстом очень четко: несколько раз говорит о том, что изменение наблюдаемого состояния программы недопустимо с помощью указателей, переданных в функцию. Единственное, что можно наблюдать из чистой функции, это ее возвращаемое значение. Изменение памяти через неконстантный указатель не возвращает значение, но побочный эффект.

Ваша функция не является чистой, поскольку имеет побочные эффекты. Если возвращаемое значение чистой функции считается неиспользованным оптимизатором, оно не должно вызываться вообще , даже в первый раз.

Следовательно, функция void бесполезна как чистая, поскольку это функция, которая должна быть оптимизируемой до void nop() { }. Это не имеет никакого смысла.

Единственная ошибка компилятора и документации здесь заключается в том, что компилятор подавил диагностику, когда вы добавили двукратно неправильное возвращение 0.


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

...