Справедливо ли маркировать Wrapper::get()
как функция в pure
члена? Это зависит только от неявного экземпляра Wrapper
, но эти данные могут измениться.
Да, Wrapper::get()
отвечает требованиям атрибута gcc pure
. Обратите внимание, однако, что __attribute__((pure))
не означает чистый в академическом смысле, т. Е. Обладающий свойством ссылочной прозрачности. Последние могут быть переданы через строже __attribute__((const))
:
__attribute__((const))
Многие функции не проверяют никаких значений, кроме своих аргументов, и не имеют никакого эффекта, кроме возвращаемого значения. В основном это всего лишь чуть более строгий класс, чем атрибут pure
ниже, так как функция не может читать глобальную память.
Обратите внимание, что функция, которая имеет указанные аргументы и анализирует данные указывали на сусло не быть объявлен const
. Аналогично, функция, которая вызывает функцию , не является функцией const
, как правило, не должна быть const
. Не имеет смысла для функции const
для возврата void
.
Но поскольку Wrapper::get()
не обладают свойством ссылочной прозрачности, подразумеваемой __attribute__((const))
, она не может быть помечены как таковые.
EDIT
Гарантия о pure
-ness (в смысле ССЗ) функции могут быть использованы для оптимизации только блок кода, который не содержит запись на глобальной памяти (и, в частности, , не перемежается вызовами функций не pure
). Примеры:
struct Wrapper {
int i;
int get() const __attribute__((pure)) { return i; }
void set(int x) { i = x; }
};
long foo(Wrapper* w)
{
// w->get() can be computed once
return 2 * w->get() * w->get();
}
long bar(Wrapper* w)
{
// w->get() can be computed once (even though below code writes to memory,
// that memory is freshly allocated and cannot be accessed by w->get())
long result = 2;
result *= w->get();
result *= w->get();
return result;
}
long baz(Wrapper* w)
{
// both w->get()s must be evaluated, since non-pure code occurs between them
long result = 2;
result *= w->get();
std::cout << "Result after the first muliplication: " << result << std::endl;
result *= w->get();
return result;
}
Эта статья может иметь отношение http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0078r0.pdf – Danh
Параметр неявного объекта (этого) все еще является параметром. Синтаксис несуществен. Вызовите if foo (x) или x.foo() или что угодно. –
@ Danh Не совсем ясно из бумаги, что ответ на этот вопрос. Это кажется несколько уклончивым. – Barry