пятница, 26 сентября 2008 г.

deprecated: gcc vs vs vs vs...

vs Visual Studio... Опять наверное прописные истины, но хочу рассказать про аттрибут deprecated.

Аттрубут deprecated - это не только ценный инструмент для командной разработки (чтобы довести до других членов команды необходимость изменения API), но так же он незаменим при рефакторинге.

Я очень часто применяю его, если мне хочется что-то удалить, но предварительно нелишним будет узнать где это что-то используется. Тогда я это что-то объявляю как deprecated, и после компиляции точно знаю файлы и строки где это используется. Вовсе не обязательно удалять сразу, есть время подумать, подчистить и когда варнинги исчезнут - удалить окончательно.

Все, про рефакторинг больше ничего не скажу.

Хочется сравнить возможности атрибутов на gcc и visual с++. Поскольку атрибуты не входят в стандарт, то в каждом компиляторе это делается как попало.

Начнем с gcc. Для объявления чего-то устаревшим в нем используется конструкция __attribute__((deprtecated)). Её можно применять для переменных и типов:
int a __attribute__((deprtecated));
struct a_struct {} __attribute__((deprtecated));
struct { int a_field __attribute__((deprtecated)); };
void func(int a_arg __attribute__((deprtecated))) {}

Практическая польза от последнего - спорна, но может пригодиться для очень больших функций. Код же разный бывает, в конце концов.

Для функций:
void func() __attribute__((deprtecated)); // в прототипе
void __attribute__((deprtecated)) func() {} // в декларации

Причем если поставить атрибут не на место, то gcc будет ругаться грязно и непонятно насчет точек с запятыми, еще какой-то фигни.

В visual c++ дело обстоит так: указание аттрибута осуществляется с помощью __declspec(deprecated) и используется практически единообразно.


__declspec(deprecated) int a;
struct __declspec(deprecated) a_struct {};
// почему после struct то?
struct { __declspec(deprecated) int a_field; };
void func(__declspec(deprecated) int a_arg) {}
// игнорируется
__declspec(deprecated) void func();

В принципе схоже, свои заморочки, но их все перекрывает возможность указать сообщение.
__declspec(deprecated("use foo instead")) void func();
В gcc такая возможность только обсуждаются.

Правда как всегда в Microsoft - без ложки дегтя не обходится. Указал сперва сообщение по русски, но в Output увидел только квадратики... только два квадратика разного размера. Хотя в сообщении было явно больше двух букв...

5 коммент.:

Анонимный комментирует...

struct __declspec(deprecated) a_struct {}; // почему после struct то?
Странно, что такого вопроса не возникло раньше несколькими строчками для __attribute__((deprtecated)).

Из-за этого ..ммм.... странного синтаксиса GCC приходится использовать некоторый изврат типа
#if defined _MCS_VER || defined __BORLANDC__ || defined __WATCOMC__
# define EXPORT(decl) __declspec(dllexport) decl
#elif defined DJGPP
# define EXPORT(decl) decl __attribute__ ((__dllexport__))
#endif

EXPORT(int fn ());

А этот AT&T синтаксис ассемблера? Все компиляторы используют нормальный __asm, даже OpenWatcom поддерживает __asm наряду с традиционной #pragma aux. И что, использовать теперь две версии асм кода? Причем можно сравнить качество кода ICC и GCC и подумать - а зачем GCC так старается сделать расширения языка несовместимыми с общепринятыми?

Так что Линус за дело попинал этих странных людей.

Указал сперва сообщение по русски
Нушотыкакмалый
Ты еще бы еще идентификаторы писал бы по русски... код вообще не скомпилился бы :-).

Указал сперва сообщение по русски, но в Output увидел только квадратики... только два квадратика разного размера. Хотя в сообщении было явно больше двух букв...
VC сохранил твое сообщение как UTF16, а компилятор вывел как ANSI наверняка... Дома посмотрю в VC2008.

Для функций:
void func() __attribute__((deprtecated)); // в прототипе
void __attribute__((deprtecated)) func() {} // в декларации

Причем если поставить атрибут не на место, то gcc будет ругаться грязно и непонятно насчет точек с запятыми, еще какой-то фигни.

Но мы-то все равно знаем, что VS хуже :-D

Андрей Валяев комментирует...

в gcc - логично...
int a deprecated;
struct s {} deprecated;
Только с фукнциями изврат...

а в vs -
deprecated int a;
но почему то не
deprecated struct s {};
Но с функциями там логично :)

Везде свои муравьи.

Я не собираюсь писать по русски идентификаторы... но ничто не может мне запретить писать по русски в кавычках!!! Я уж не говорю про комментарии. :)

Анонимный комментирует...

Не, не логично. Почему спецификатор пишется после имени функции? Спецификатор inline пишется в одном месте, deprecated совершенно в другом. К тому же непонятно, почему GCC идет своим путем, даже не пытаясь поддержать совместимость с другими распространенными компиляторами. Это вынуждает использовать function-like макросы для объявления и определения функций. Дело принципа? M$ - денежные мешки, а мы - свободное ПО, и поэтому не ориентируемся на этих гадов?

extern __declspec(deprecated) int a;
extern int __declspec(deprecated) a;
__declspec(deprecated) int fn();
int __declspec(deprecated) fn();
class __declspec(deprecated) a {};
Да,
__declspec(deprecated) class a {};
такого нету. Но тенденция все равно ясна.
inline int a(){...}
int inline a(){...}
Причем даже Borland рекоммендовала использовать __declspec(dllexport) вместо _export, т.к. __declspec предоставляет большую гибкость в написании.

Насчет муравьев согласен. MSVC6 ввел __declspec(property), удобная штука, но непонятно почему блин плохо реализованная. С другой стороны, __declspec(property) больше я ни в одном компилере другой фирмы не видел, и предоставляет это только академический интерес :-) Так что я даже рад, что не использовал это в проектах.

Насчет __declspec(deprecated("text"))
Да, в VisualC 2008 есть такая проблема. Причем непонятно почему так все получается. Похоже, на самом деле MBCS/Unicode проблема.

но ничто не может мне запретить писать по русски в кавычках!!!
Ты по прежнему в этом уверен :-D ?

Я уж не говорю про комментарии.
Комментарии в наше время должны идти на международном языке, особенно если работаешь в OpenSource или совместной компании. Если большой проект сегодня пишется с российскими программистами, в будущем компания может взять фрилансеров из.... Китая, например.

Андрей Валяев комментирует...

2coff: Комментарии в наше время должны идти на международном языке, особенно если работаешь в OpenSource или совместной компании. Если большой проект сегодня пишется с российскими программистами, в будущем компания может взять фрилансеров из.... Китая, например.

Очень спорный вопрос... для меня лично. :)

С одной стороны конечно, если я хочу чтобы мое ПО завоевало мир - надо писать по английски даже в исходниках...

С другой стороны я достаточно трезво оцениваю свой английский, чтобы засомневаться в том, что могу внято выразить что-то непонятное в комментарии на английском. :)

Предпочитаю писать говорящий код, Чтобы его можно было понимать и без комментариев. Но комментарии всеравно пишу по русски. :) чтобы русский язык завоевал мир... :) Пусть буржуи блин изучают русский. :)

Анонимный комментирует...

надо писать по английски даже в исходниках...
Я об этом и говорю. Сообщения-то локализуются, это не проблема (если это не #error, #pragma message или __declspec(deprecated(""))).

В некоторых конторах обязывают писать комментарии по английски. Надо будет - быстро подтянешься :-)

Имхо, лучше хоть как-то писать на международном языке, чем никак.

Предпочитаю писать говорящий код, Чтобы его можно было понимать и без комментариев.
Обычная отмазка иксоидов :-)