Новый стандарт С++14 вводит атрибут deprecated для пометки устаревших сущностей, планируемых к удалению в дальнейшем. Компилятор может выводить предупреждения при любой попытке их использования. Синтаксис принципиально новый для С++: атрибуты предполагается писать в виде списка через запятую, внутри двойных квадратных скобок. Вот так выглядит функция, помеченная как deprecated:
[[deprecated]] void foo() {} int main() { foo(); // в этом месте компилятор выведет предупреждение }
Другие возможные атрибуты: noreturn, carries_dependency, alignas
Код выше, будучи скомпилированным последним билдом clang, выдаёт следующее сообщение на этапе компиляции:
warning: 'foo' is deprecated [-Wdeprecated-declarations] foo(); ^ note: 'foo' has been explicitly marked deprecated here void foo() {} ^
Также возможно вывести собственное сообщение:
[[deprecated("use bar instead")]] void foo() {} This gives the following warning instead: warning: 'foo' is deprecated: use bar instead [-Wdeprecated-declarations] foo(); ^ note: 'foo' has been explicitly marked deprecated here void foo() {} ^
Атрибут deprecated также применим к классам, typedef-ам, переменным, не статическим членам данных, перечислениям и шаблонам. Вот пара примеров:
// помечаем функцию [[deprecated]] void foo(); // помечаем переменную [[deprecated]] int x; // помечаем только одну переменную в списке определяемых int y [[deprecated]], z; // помечаем параметр функции int triple([[deprecated]] int x); // помечаем класс или структуру class [[deprecated]] my_class { public: // помечаем член класса [[deprecated]] int member; }; // помечаем перечисление enum [[deprecated]] animals { CAT, DOG, MOUSE }; // помечаем typedef [[deprecated]] typedef int type; // помечаем шаблон template <typename T> class templ; template <> class [[deprecated]] templ<int> {};
Для тех, кто отмечает бросающуюся в глаза неконсистентность размещения атрибутов (к примеру их использование после ключевых слов class и enum) скажу, что это для того, чтобы можно было отличить пометку самого типа от пометки переменной этого типа. Например, следующее объявление помечает переменную, но не сам класс:
[[deprecated]] class C { } c;
Атрибут deprecated может быть указан только в одном определении некоторой сущности, все следующие объявления без данного атрибута не снимают атрибут deprecated. Лучше всего помещать атрибут в заголовочный файл — этим вы подскажете всем пользователям, что сущность устарела и будет удалена.
Атрибут поддерживается начиная с Clang 3.4 и GCC 4.9.
Примечания переводчика: атрибуты, появившиеся ещё в стандарте С++11 подавали большие надежды — новая возможность добавлять метаданные к функциям, классам и другим вещам потенциально открывали большие возможности для мета-программирования, рефлексии, тестирования — в конце-концов C# и Python уже доказали реальную пользу подобных инструментов языка и лично мне хотелось верить, что и С++ получит в будущем что-то подобное. К сожалению, первые введённые атрибуты (noreturn, carries_dependency, alignas) давали как-то маловато пользы, что портило положительное впечатление от фичи. deprecated — первый, на мой взгляд, реально простой, понятный и нужный каждому атрибут. Хочется верить, что это шаг на пути к дальнейшим фичам языка на основе атрибутов.
ссылка на оригинал статьи http://habrahabr.ru/company/infopulse/blog/231227/
Добавить комментарий