2016-11-23 4 views
14

ССАГПЗА документации для __attribute__((pure)) состояний:Комментирование константной функции-члена с чистым атрибутом

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

Что означает только зависеть от параметров? Рассмотрим:

struct Wrapper { 
    int i; 

    int get() const { return i; } 
    void set(int x) { i = x; } 
}; 

Справедливо ли маркировать Wrapper::get() как функция в pure члена? Это зависит только от неявного экземпляра Wrapper, но эти данные могут измениться.

+1

Эта статья может иметь отношение http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0078r0.pdf – Danh

+1

Параметр неявного объекта (этого) все еще является параметром. Синтаксис несуществен. Вызовите if foo (x) или x.foo() или что угодно. –

+0

@ Danh Не совсем ясно из бумаги, что ответ на этот вопрос. Это кажется несколько уклончивым. – Barry

ответ

4

Справедливо ли маркировать 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; 
} 
+0

Вы уверены в '__attribute __ ((const))'? Разве не подразумевается 'this' аргумент указателя на функцию? – Barry

+0

@Barry См. Обновленный ответ – Leon

+0

Я не уверен, что добавление термина «ссылочная прозрачность» помогает. Означает ли этот термин определенный смысл? Является ли 'strlen()' не ссылочно прозрачным? – Barry

Смежные вопросы