int main()
{
bool b1 = fff(1, ID); // Компилируется
ignore_result(fff(2, ID)); // Компилируетсяif (fff(2, ID)); // Компилируется
fff(1, ID); // НЕ Компилируется! error C2027: use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'
}
К сожалению параметр RESULT_CHECK_PARAM — необходимость — сейчас будет видно. Собственно исходный код:
// Стратегии сообщения об ошибке (куда сейчас без стратегий? :) )
// На выбор - ошибка компиляции, варнинг, ошибка без использования boost (специально для нелюбителей boost'а :) )struct error_report_policy
{
template<typename> static void report()
{
BOOST_STATIC_ASSERT(false);
}
};
struct error_report_no_boost_policy
{
template<typename> static void report()
{
typedef char error[-1];
}
};
struct warning_report_policy
{
template<typename> static void report()
{
BOOST_STATIC_WARNING(false);
}
};
namespace
{
// Вспомогательный класс - ниже будет видно зачемtemplate<int id>
struct result_check_helper
{
static void fake() {}
};
}
// Собственно класс для возвращаемого значения
// id - вспомогательный параметр
// type - тип возвращаемого значения - bool, int, HRESULT и т.д.
// report_policy - одна из вышеприведённых стратегий информирования об ошибкеtemplate<int id, typename type = bool, typename report_policy = error_report_policy>
class checked_result
{
public:
checked_result(type value)
: value_(value)
{}
operator type ()
{
// Обращаемся к классу result_check_helper<id>
// ниже будет видно зачем
result_check_helper<id>::fake();
return value_;
}
~checked_result()
{
// ЗДЕСЬ!
// Определяем есть ли класс result_check_helper<id>,
// что фактически равнозначно тому, вызывается operator type () или нет!
__if_not_exists (result_check_helper<id>)
{
report_policy::report<void>();
}
}
private:
type value_;
};
// Вспомогательный класс для передачи уникальных идентификаторов вызоваtemplate<int id> struct long_and_inconvenient_name {static const int id = id;};
// Вспомотельный макрос для генерации уникальных идентификаторов вызова
// В реальности надо какое-то более длинное имя, чем ID, но здесь для простоты так#define ID long_and_inconvenient_name<__COUNTER__>()
// Вспомогательный макрос#define RESULT_CHECK_PARAM long_and_inconvenient_name<id>
// Функции для явного игнорирования возвращаемого значенияinline void ignore_result(bool) {}
inline void ignore_result(int) {}
//...
Да вы батенька знаете толк в извращениях. Знатный велосипед.
Это все фигня. Вы воспользовались MS-extention __if_not_exist, а раз вы им воспользовались то заведомо прилипли к платформе
У MS есть решение подобного рода встроеное в компилер, которое кстати сказать работает на порядок лучше
// C++#include <codeanalysis\sourceannotations.h>
using namespace vc_attributes;
[returnvalue:Post(MustCheck=Yes)] int fff();
я получил такой вот варнинг
warning C6031: Return value ignored: 'fff'
PS:для этого надо врубить code-analysys в свойствах проекта.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: А может по-человечески как-то это сделать? :)
Здравствуйте, remark, Вы писали:
R>Без форсирования: R>1. Неправильный код написать легче, чем правильный
Называй функции понятнои с простой и ясной семантикой, избегая при этом всяких синтаксических трюков и неявно генерирующегося и вызываемого кода -- и будет тебе счастье R>2. Не явны намерения программиста: он забыл проверить или хотел это сделать?
Ну коглда программист вменяемый, то и не страшно, а когда невменяемый, то он обойдёт твою приблуду на раз-два-три R>3. Код менее читабельный: f() — а эта функция что-то ещё и возвращает?
Ну вот скажи, про какую из функций не понятно возвращает она что-то или нет?
Может просто отказаться от возврата кодов ошибок, а API всегда звать через C++ warper?
Тогда информацию об ошибках игнорировать будет нельзя. Обрабатывать её будут в удобных местах, а нужно ли значение, возвращаемое функцией будет понятно из её названия.
Скажем функция CopyFiles( ... ) ничего не возвращает, а GetCopiedFilesCount() -- возвращает
А, скажем такая или анологичная конструкция:
Вообще искоренит проблему на корню R>Форсирование решает все эти проблемы.
Короче, ИМХО, лучше подходить с другого конца. Не заставлять при помощи плохо переносимых и очень сложных и не особо понятных трюков программиста делать то, что делать на самом деле неудобно, а так обустроить архитектуру и технологию программирования, что неудобные действия станут ненужными
R>
Да не вопрос!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: А может по-человечески как-то это сделать? :)
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, remark, Вы писали:
R>>
Свершилось! Форсирование проверки возвращаемого значения в компайл-тайм возможно!
R>>В начале несколько вводных слов, что б было понятно о чём речь:
R>>Работает на msvc71/80. В рантайм оверхед нулевой.
R>>
NB>может стоит ID сделать первым параментром, на случай если у функции есть параметры по умолчанию?
Это можно варьировать по желанию для каждой функции.
В данном случае просто хотелось более показать сходство с оригинальной функцией.
NB>PS: а что, действительно большая проблема в проверкой?
"IROV.." <35375@users.rsdn.ru> wrote in message news:2279806@news.rsdn.ru... > Здравствуйте, remark, Вы писали: > > R>
Свершилось! Форсирование проверки возвращаемого значения в компайл-тайм возможно!
> > как по мне на лицо борьба с ветряными мельницами! а именно, ну а кто мне _леньтяю_ запретит писать вот такое.. > >
> if( foo( 1, 2 ) );
>
> >
Так в этом то и состоит цель этой затеи, чтоб заставить пользователя так писать. Таким образом пользователь как бы говорит: "я осознанно проигнорировал результат, всю ответственность беру на себя...".
Цель, вообще говоря, хорошая, но, имхо, не такой ценой как в предлагаемом варианте: один только макрос RESULT_CHECK_PARAM чего стоит.
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[8]: А может по-человечески как-то это сделать? :)
Здравствуйте, np9mi7, Вы писали:
N>Здравствуйте, remark, Вы писали:
R>>В смысле?
N>Насколько я понял, твоё решение накладывает такое ограничение, поэтому не является полноценной заменой этого расшерения (без учета дополнительного параметра);
Да, есть такая фигня. Решение вообще далеко до.... до чего-либо
Для решения именно это проблемы можно разместить само "ядро" функции как и раньше в cpp файле, а в h файле оставить только шаблонную обёртку, которая будет форвардить вызов. Тут только надо будет как-то сделать, что бы пользователи не могли вызывать само "ядро" т.к. иначе весь смысл теряется. Тут наверное можно что-то замутить с недоступными членами и друзьями.
Прикольно, но ИМХО неудобства написания шаблонного враппера к каждому нешаблонному методу здесь слишком большие. И это не удовлетворяет более ранним требования — "есть дофига старого кода, хочу проверить ошибки там" — нужен параметр ID.
Можно конечно макросы ещё написать — #define Foo(x) Foo(x, ID), но это всё более и более уход в Темную Сторону.
или code guide с написанием скрипта — "эту функцию можно вызывать только так — ^bool :i = foo\(.*\);$ и как if \(.*foo" (это не реальные регэкспы а просто как начинать их писать)
Можно даже скрипт не писать, а сразу Edit->Find In Files. И заграть в макрокнопку студии.
Правильно работающая программа — просто частный случай Undefined Behavior
Re: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, rg45, Вы писали:
R>Так в этом то и состоит цель этой затеи, чтоб заставить пользователя так писать. Таким образом пользователь как бы говорит: "я осознанно проигнорировал результат, всю ответственность беру на себя...". R>Цель, вообще говоря, хорошая, но, имхо, не такой ценой как в предлагаемом варианте: один только макрос RESULT_CHECK_PARAM чего стоит.
Хочу не согласится! если честно то если програмист _ленивый_, то он напишет именно if(...); только по томучто ему лень, а потом забудет как всегда.
Я вот понимаю сделать чтото типа такого..
result r = foo( ... );
r.check_result(); // для подтверждения того что я оттестил. тогда я хоть по ctrl + F смогу отыскать все такие места, и поправить если что забыл..
Конечно это оверхед, но его можно отключать в релизе!
я не волшебник, я только учусь!
Re[6]: А может по-человечески как-то это сделать? :)
... E>Короче, ИМХО, лучше подходить с другого конца. Не заставлять при помощи плохо переносимых и очень сложных и не особо понятных трюков программиста делать то, что делать на самом деле неудобно, а так обустроить архитектуру и технологию программирования, что неудобные действия станут ненужными
Со всем согласен. От себя добавлю, что так же полезно писать к функциям нормальные комментарии и не лениться их читать. Если обработка возвращаемого значения необходима — не поленитесь и отразите это в комментарии.
Душа обязана трудиться! (с) Н.Заболоцкий.
Re[7]: А может по-человечески как-то это сделать? :)
Здравствуйте, _Obelisk_, Вы писали:
_O_>Здравствуйте, Erop, Вы писали:
_O_>... E>>Короче, ИМХО, лучше подходить с другого конца. Не заставлять при помощи плохо переносимых и очень сложных и не особо понятных трюков программиста делать то, что делать на самом деле неудобно, а так обустроить архитектуру и технологию программирования, что неудобные действия станут ненужными
_O_>Со всем согласен. От себя добавлю, что так же полезно писать к функциям нормальные комментарии и не лениться их читать. Если обработка возвращаемого значения необходима — не поленитесь и отразите это в комментарии.
Это смешно. Пользователи читают документацию только в исключительных случаях. Вариант, когда можно и так написать работающий код не относится к исключительным случаям.
Здравствуйте, remark, Вы писали:
R>Это смешно. Пользователи читают документацию только в исключительных случаях. Вариант, когда можно и так написать работающий код не относится к исключительным случаям.
Хм. Я всегда читаю документацию или комментарии на функции, которые собираюсь использовать. Коллеги тоже.
Мы говорим ведь от девелоперах, а не о конечных потребителях. Излишние навороты на пустом месте не нужны.
Душа обязана трудиться! (с) Н.Заболоцкий.
Re[8]: А может по-человечески как-то это сделать? :)
Здравствуйте, igna, Вы писали:
I>Ты прав. Но если что-то можно выразить на языке программирования, использовать для этого комментарий не стоит.
Почему тебе кажется, что куча из шаблонов, макросов и особых вызывалок выражает именно это лучше, чем просто комментарий и понятное название функции с ясной семантикой?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: А может по-человечески как-то это сделать? :)
E>>Называй функции понятнои с простой и ясной семантикой, избегая при этом всяких синтаксических трюков и неявно генерирующегося и вызываемого кода -- и будет тебе счастье
R>Ну вот например. И чего? И что отсюда следует? R>
R>Во-первых, это будет видно, что здесь что-то обойдено (сравните с "здесь не будет ничего видно"). R>Во-вторых, раз уж надо что-то обходить, то уже есть шанс, что программист задумается, может ему не обойти, а сделать нормальную проверку. R>Обратный вариант — программист просто пишет минимум кода без проверки, этого не видно, не понятно, он это хотел или забыл.
Ну и пишет он без проверки. А ещё может переменные не инициализировать. А ещё ODR может нарушать. И что?
ИМХО есть такие проблемы, против которых бороться средствами самого C++ сложнее, чем не бороться E>>Ну вот скажи, про какую из функций не понятно возвращает она что-то или нет? E>>
R>Ни про какую.
ИМХО последние две не должны ничего возвращать. А первая должна либо получать на вход параметр для заполнения, либо должна возвращать качество E>>Может просто отказаться от возврата кодов ошибок, а API всегда звать через C++ warper? R>Так подожди, ты сам за что? что бы надеяться на мифического вменяемого, неленивого, у_которого_всегда_есть_время, который_не_работает_поздно, который_не_работает_по_14_часов, который_ничего_не_забывает и_т_д программиста, или за то, что бы делать интерфейс, который трудно использовать неправильно при любых обстоятельствах?
Я за то, чтобы борьба с проблемой не была хуже самой проблемы
В частности, если уж тебе так важно проверять использование возврата какой-то функции (и никак никак нельзя переформулировать эту функцию), то используй средства анализа кода, отличные от C++ компилятора. Они реально намного удобнее E>>Вообще искоренит проблему на корню R>Какаим образом?
Ну таким образом, что если случается исключительная ситуация, то происходит обработка через механизм исключений.
А если тебе надо скопировать, то скопируешь, а если надо узнать сколько таки файлов скопировалось, то узнаешь сколько скопировалось.
Я, например, ещё и assert'ы всюду пишу, и assert у меня свой, который в release-версии не откулючается R>Есть по-крайней мере 2 случая, когда это не возможно: R>1. Исключения использовать нельзя — это предусловие
Насколько мне подсказывает мой опыт, использовать твой велосипед там, где нельзя использовать исключения, тем более не получится R>2. Исключения не прикрутишь к интерфейсу. Вот пример:
Какие проблемы?
Может таки лучше иметь два метода? Один для команд, которые точно должны выполниться, а другой для команд, которые могут быть выполненны.
Ещё лучше, если удастся сформулировать два метода.
1) вовращает значение: "можно ли ещё раз выполнить"
2) выполняет, а если не смог -- ошибка
Тогда и циклы писать будет удобно, типа тиак:
while(cmd.CanFetch() ) {
cmd.Fetc();
}
и просто плоский код будет просто писать:
cmd.Fetch(); // Эта запись всегда есть. Ну просто зуб даю!!!
и код в стиле if(!...) { обработка ошибки } тоже удобно пишется:
if( !cmd.CanFetch() ) {
// тут какая-то хитрая обработка, отличная от просто ошибки в Fetch
} else {
cmd.Fetch();
}
И везде всё понятно и никакого форсирования не надо
Мало того, если вдруг метод CanFetch() от чего-то очень трудно написать или неэффективно, скажем, можно и так сделать:
while( cmd.FetchIfCan() ) {
// тут чего-то, что надо
}
да и
cmd.Fetch(); // Эта запись всегда есть. Ну просто зуб даю!!!
совсем не изменится
Ну а третий контекст, тоже будет простой и понятный:
if( !cmd.FetchIfCan() ) {
// тут какая-то хитрая обработка, отличная от просто ошибки в Fetch
}
ИМХО так намного понятнее, чем чудовище из хитроприкрученных шаблонов, да ещё и существенно опирающихся на конкретную реализацию
Тогда уж лучше просто штатными коданализаторами полтзоваться. По крайней мере предсказуемее результат
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, _Obelisk_, Вы писали:
_O_>Здравствуйте, remark, Вы писали:
R>>
Свершилось! Форсирование проверки возвращаемого значения в компайл-тайм возможно!
R>>В начале несколько вводных слов, что б было понятно о чём речь:
_O_>Супер! Только вопрос — зачем? _O_>Если программист хочет игнорировать возвращаемое значение — пущай игнорирует.
здесь Andrei Alexandrescu пишет, что проверка — хорошо.
Вот цитата оттуда:
I'm very happy with this solution. Of course, it still doesn't prevent
perverse programmers from saying:
(bool) Fun();
but I ignore perversity. I care only about carelesness.
Вот собственно ответ на твой вопрос: but I ignore perversity. I care only about carelesness.
Здравствуйте, _Obelisk_, Вы писали:
_O_>Здравствуйте, remark, Вы писали:
R>>
Свершилось! Форсирование проверки возвращаемого значения в компайл-тайм возможно!
R>>В начале несколько вводных слов, что б было понятно о чём речь:
_O_>Супер! Только вопрос — зачем? _O_>Если программист хочет игнорировать возвращаемое значение — пущай игнорирует.
Я думаю, это одна из тех вещей, которые не объяснить. Те, кто поняли зачем, тем понятно, а те кто не поняли, тем не объяснить.
Ну это типа как "А зачем программировать на С++, когда есть С?" или "Зачем использовать исключения, когда есть коды возврата?"
Здравствуйте, IROV.., Вы писали:
IRO>Здравствуйте, remark, Вы писали:
IRO>...
IRO>
IRO>fff(1, ID /* - фээ некрасиво */ );
IRO>
IRO>
Согласен.
Но во-первых, надо с чего-то начинать. Это первый рабочий вариант, который я видел (который работает и для методов). На rsdn точно ничего аналогичного нет, в других местах тоже не видел. В Overload ещё не так давно кто-то писал про вариант типа здесь
Здравствуйте, johny5, Вы писали:
J>Ну во первых нужно было прям перед заголовком вот так написать: J>Microsoft specific J>Я может дальше и читать бы не стал
Читай внимательнее:
В gcc для этих целей есть __attribute__((warn_unused_result)). Но что делать пользователям msvc?
J>Тут наверно таки вызов fff_wrap?
Да, конечно, описался...
J>Я так понимаю, при каждом вызове такой функции, будет инстанцироваться result_check_helper<int id>::fake() J>У линкера башню то не порвёт? J>
Нет. Тем более, что символ с внутренним связыванием.
Как вы думайте сколько реализаций функции fff_wrap в бинарнике ?
Вряд ли такое поведение функции ожидается, а отказ от статических переменных в функции ИМХО слишком суров.
Re[4]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, Antipov, Вы писали:
A>Как вы думайте сколько реализаций функции fff_wrap в бинарнике ? A>Вряд ли такое поведение функции ожидается, а отказ от статических переменных в функции ИМХО слишком суров.
R>Я думаю, это одна из тех вещей, которые не объяснить. Те, кто поняли зачем, тем понятно, а те кто не поняли, тем не объяснить. R>Ну это типа как "А зачем программировать на С++, когда есть С?" или "Зачем использовать исключения, когда есть коды возврата?"
На эти два вопросы имеются ответы, а вот необходимости в compile-time проверки учета возвращаемого значения не вижу.
Душа обязана трудиться! (с) Н.Заболоцкий.
Re[4]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, _Obelisk_, Вы писали:
_O_>Здравствуйте, remark, Вы писали:
R>>Я думаю, это одна из тех вещей, которые не объяснить. Те, кто поняли зачем, тем понятно, а те кто не поняли, тем не объяснить. R>>Ну это типа как "А зачем программировать на С++, когда есть С?" или "Зачем использовать исключения, когда есть коды возврата?"
_O_>На эти два вопросы имеются ответы, а вот необходимости в compile-time проверки учета возвращаемого значения не вижу.
Без форсирования:
1. Неправильный код написать легче, чем правильный
2. Не явны намерения программиста: он забыл проверить или хотел это сделать?
3. Код менее читабельный: f() — а эта функция что-то ещё и возвращает?
Здравствуйте, rm822, Вы писали:
R>Да вы батенька знаете толк в извращениях. Знатный велосипед. R>Это все фигня. Вы воспользовались MS-extention __if_not_exist, а раз вы им воспользовались то заведомо прилипли к платформе R>У MS есть решение подобного рода встроеное в компилер, которое кстати сказать работает на порядок лучше
R>
R>// C++
R>#include <codeanalysis\sourceannotations.h>
R>using namespace vc_attributes;
R>[returnvalue:Post(MustCheck=Yes)] int fff();
R>
R>я получил такой вот варнинг R>warning C6031: Return value ignored: 'fff'
R>PS:для этого надо врубить code-analysys в свойствах проекта.
Весь флейм зря..
токо вот у меня:
Compiling...
cl : Command line warning D9040 : ignoring option '/analyze'; Code Analysis warnings are not available in this edition of the compiler
SP1?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, Vain, Вы писали: V>SP1?
ХЗ, у меня TeamSuite , а в MSDN не написано про то в каких эдишнах это работает.
Сам пользуюсь мне нравится, анализ хороший хотя и не быстрый, варнингов много. В паре с C++ test так вообще отлично.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, rm822, Вы писали:
R>Здравствуйте, Vain, Вы писали: V>>SP1? R>ХЗ, у меня TeamSuite , а в MSDN не написано про то в каких эдишнах это работает. R>Сам пользуюсь мне нравится, анализ хороший хотя и не быстрый, варнингов много. В паре с C++ test так вообще отлично.
Я уже потом подумал про team suit, хотя уже нашёл:
/analyze is only available in Enterprise (team development) versions for x86 compilers.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Без форсирования: R>>1. Неправильный код написать легче, чем правильный E>Называй функции понятнои с простой и ясной семантикой, избегая при этом всяких синтаксических трюков и неявно генерирующегося и вызываемого кода -- и будет тебе счастье
R>>2. Не явны намерения программиста: он забыл проверить или хотел это сделать? E>Ну коглда программист вменяемый, то и не страшно, а когда невменяемый, то он обойдёт твою приблуду на раз-два-три
Во-первых, это будет видно, что здесь что-то обойдено (сравните с "здесь не будет ничего видно").
Во-вторых, раз уж надо что-то обходить, то уже есть шанс, что программист задумается, может ему не обойти, а сделать нормальную проверку.
Обратный вариант — программист просто пишет минимум кода без проверки, этого не видно, не понятно, он это хотел или забыл.
R>>3. Код менее читабельный: f() — а эта функция что-то ещё и возвращает? E>Ну вот скажи, про какую из функций не понятно возвращает она что-то или нет? E>
E>Может просто отказаться от возврата кодов ошибок, а API всегда звать через C++ warper?
Так подожди, ты сам за что? что бы надеяться на мифического вменяемого, неленивого, у_которого_всегда_есть_время, который_не_работает_поздно, который_не_работает_по_14_часов, который_ничего_не_забывает и_т_д программиста, или за то, что бы делать интерфейс, который трудно использовать неправильно при любых обстоятельствах?
Я, лично, за второй вариант. Но я вижу, что тут есть люди, которые за первый вариант...
Я сам обеими руками за исключения, но иногда _надо_ использовать коды возврата, а иногда семантика функции такая, что исключения к ней не сделаешь.
E>Тогда информацию об ошибках игнорировать будет нельзя. Обрабатывать её будут в удобных местах, а нужно ли значение, возвращаемое функцией будет понятно из её названия. E>Скажем функция CopyFiles( ... ) ничего не возвращает, а GetCopiedFilesCount() -- возвращает E>А, скажем такая или анологичная конструкция:
Какаим образом?
R>>Форсирование решает все эти проблемы.
E>Короче, ИМХО, лучше подходить с другого конца. Не заставлять при помощи плохо переносимых и очень сложных и не особо понятных трюков программиста делать то, что делать на самом деле неудобно, а так обустроить архитектуру и технологию программирования, что неудобные действия станут ненужными
Это замечательно... если возможно. Опять же исключения решают проблему.
Можно поглядеть здесь статья "A Return Type That Doesn’t Like Being Ignored".
Есть по-крайней мере 2 случая, когда это не возможно:
1. Исключения использовать нельзя — это предусловие
2. Исключения не прикрутишь к интерфейсу. Вот пример:
class DBCmd
{
...
bool Fetch();
...
};
Очень удобно использовать так:
DBCmd cmd;
...
while (cmd.Fetch())
{
...
}
Для одной записи, это должно выглядеть так:
DBCmd cmd;
...
if (!cmd.Fetch())
обработка_ошибки
Но, к сожалению, очень часто пишется такой код:
DBCmd cmd;
...
cmd.Fetch();
С объяснениями типа — ну эта запись там должна быть всегда...
"_Obelisk_" <18435@users.rsdn.ru> wrote in message news:2280075@news.rsdn.ru... > Здравствуйте, Erop, Вы писали: > > ... > Со всем согласен. От себя добавлю, что так же полезно писать к функциям нормальные комментарии и не лениться их читать. Если обработка возвращаемого значения необходима — не поленитесь и отразите это в комментарии.
Ксожалению, в том месте, где функция используется, этот комментарий не виден. Да и неудобно при чтении текста программы для каждой функции искать ее объявление для того, чтобы почитать комментарий. Гораздо лучше, если названия функций говорят сами за себя и не нуждаются в комментариях.
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, _Winnie, Вы писали:
_W>Здравствуйте, remark, Вы писали:
_W>Прикольно, но ИМХО неудобства написания шаблонного враппера к каждому нешаблонному методу здесь слишком большие.
Согласен. Это всё есть. Но это отправная точка, а не законченный солюшн. Смотри мой ответ здесь
Если вы думаете, что, я считаю, что вызов "f()" — это слишком просто и не катит, и что обязательно надо к нему навернуть макросов, доп параметров, шаблонов и т.д. То это не так. Мне просто "f()" тоже гораздо больше нравится. Но тут это была необходимость.
_W>И это не удовлетворяет более ранним требования — "есть дофига старого кода, хочу проверить ошибки там" — нужен параметр ID.
_W>или code guide с написанием скрипта — "эту функцию можно вызывать только так — ^bool :i = foo\(.*\);$ и как if \(.*foo" (это не реальные регэкспы а просто как начинать их писать) _W>Можно даже скрипт не писать, а сразу Edit->Find In Files. И заграть в макрокнопку студии.
А разьве не приятнее просто компилировать программу как всегда, и что бы компилятор показывал ошибки?
Здравствуйте, rm822, Вы писали:
R>Да вы батенька знаете толк в извращениях. Знатный велосипед. R>Это все фигня. Вы воспользовались MS-extention __if_not_exist, а раз вы им воспользовались то заведомо прилипли к платформе
Я прилип к платформе ещё до этого, когда появилось требование разработки под win32 на msvc. И я думаю, что я не одинок.
Прилипание к самой распространённой платформе и самому распространённому компилятору имхо не так страшно.
И я это указал в начале поста.
R>У MS есть решение подобного рода встроеное в компилер, которое кстати сказать работает на порядок лучше R>PS:для этого надо врубить code-analysys в свойствах проекта.
Это замечательно. Вы совсем плохо обо мне думаете.
Но это работает только под msvc80 enterprise, и сдаётся мне, что раз аттрибуты, то ещё и c++/cli.
Хотелось бы решение для msvc71/80 всех версий, и без cli.
Здравствуйте, igna, Вы писали:
I>Здравствуйте, _Obelisk_, Вы писали:
_O_>>От себя добавлю, что так же полезно писать к функциям нормальные комментарии и не лениться их читать.
I>Ты прав. Но если что-то можно выразить на языке программирования, использовать для этого комментарий не стоит.
Рад, что хоть кто-то меня понимает, зачем я это делаю.
Здравствуйте, remark, Вы писали:
R>Это замечательно. Вы совсем плохо обо мне думаете.
Я хорошо думаю о вас, но то что вы изобретаете это конечно интересно но не более того, С++ не приспособлен для контрактного программирования (compile-time) и этим все сказано. R>Но это работает только под msvc80 enterprise, и сдаётся мне, что раз аттрибуты, то ещё и c++/cli.
Это работает без cli.
PS: 2000$ — существенная сумма для отдельного человека а не для комманды — если ваша комманда решила серьезно этим заняться 2кб не препятствие, к тому же trial 180 дневный кажется никто не отменял.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, rm822, Вы писали:
R>Здравствуйте, remark, Вы писали:
R>>Это замечательно. Вы совсем плохо обо мне думаете. R>Я хорошо думаю о вас, но то что вы изобретаете это конечно интересно но не более того, С++ не приспособлен для контрактного программирования (compile-time) и этим все сказано.
Имхо "интересные" вещи очень ценны. Возможно в данном применении она ("интересная" вещь) воплотилась не в полностью практическом решении. Зато возможно позднее кто-то сделает на её основе что-то действительно практическое и с превосходными характеристиками, чего без этой "интересной" вещи сделать было бы нельзя.
В boost можно найти много примеров "интересных" вещей, которые тем не менее воплотились в очень практические решения.
Например, sfinae многие (и я) несколько лет назад воспринимали как "интересную" и "забавную" фичу.
R>>Но это работает только под msvc80 enterprise, и сдаётся мне, что раз аттрибуты, то ещё и c++/cli. R>Это работает без cli.
Они дабавили аттрибуты (которые в []) и в с++? А рефлекшн есть?
Здравствуйте, remark, Вы писали:
R>Здравствуйте, rm822, Вы писали:
R>>Здравствуйте, remark, Вы писали:
R>>>Это замечательно. Вы совсем плохо обо мне думаете. R>>Я хорошо думаю о вас, но то что вы изобретаете это конечно интересно но не более того, С++ не приспособлен для контрактного программирования (compile-time) и этим все сказано.
R>Имхо "интересные" вещи очень ценны. Возможно в данном применении она ("интересная" вещь) воплотилась не в полностью практическом решении. Зато возможно позднее кто-то сделает на её основе что-то действительно практическое и с превосходными характеристиками, чего без этой "интересной" вещи сделать было бы нельзя.
Очень(!) некоторые ценны, остальные просто интересны.
R>Они дабавили аттрибуты (которые в []) и в с++? А рефлекшн есть?
Вроде бы нет. Есть интеграция с БД, все эти занудные стандартные обертки для таблиц. Что-то для комов добавили.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: А может по-человечески как-то это сделать? :)
Здравствуйте, remark, Вы писали:
_O_>>Со всем согласен. От себя добавлю, что так же полезно писать к функциям нормальные комментарии и не лениться их читать. Если обработка возвращаемого значения необходима — не поленитесь и отразите это в комментарии.
R>Это смешно. Пользователи читают документацию только в исключительных случаях. Вариант, когда можно и так написать работающий код не относится к исключительным случаям.
А может таки попробовать семантику функций продумывать?
Чтобы не было смысла вызывать функци, игнорируя её значение?
R>
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: А может по-человечески как-то это сделать? :)
Здравствуйте, remark, Вы писали:
R>В gcc для этих целей есть __attribute__((warn_unused_result)). Но что делать пользователям msvc? (забить на msvc и перейти на gcc не предлагать )
Не являюсь пользователем g++, но неужели расширение языка в виде __attribute__((warn_unused_result)) накладывает ограничение наличия определения и объявления в одной единице трансляции?
В основном идея понравилась
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[2]: [Trick] Форсирование проверки возвращаемого значения
Здравствуйте, np9mi7, Вы писали:
N>Здравствуйте, remark, Вы писали:
R>>В gcc для этих целей есть __attribute__((warn_unused_result)). Но что делать пользователям msvc? (забить на msvc и перейти на gcc не предлагать )
N>Не являюсь пользователем g++, но неужели расширение языка в виде __attribute__((warn_unused_result)) накладывает ограничение наличия определения и объявления в одной единице трансляции?
Насколько я понял, твоё решение накладывает такое ограничение, поэтому не является полноценной заменой этого расшерения (без учета дополнительного параметра);
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re: [Trick] Форсирование проверки возвращаемого значения
Свершилось! Форсирование проверки возвращаемого значения в компайл-тайм возможно!
А как сделать чтобы всёэто работало на msvc6.0
R>Работает на msvc71/80. В рантайм оверхед нулевой.
R>
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!