Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно?
Как ни странно на форуме ничего похожего не нашёл...
Например:
bool some_func();
if (some_func()); // компилируетсяbool result = some_func(); // компилируется
some_func(); // не должно компилироваться
Здравствуйте, remark, Вы писали:
R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>Как ни странно на форуме ничего похожего не нашёл...
Думаю, это невозможно.
Функция some_func() должна возвращать результат, который будет неявно приводится к bool (требование для if ( condition ) statement).
Следовательно, в месте, помеченном как "не должно компилироваться", просто произойдет вычисление этого выражения — и все (к сожалению) скомпилируется.
Здравствуйте, remark, Вы писали:
R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>Как ни странно на форуме ничего похожего не нашёл...
On Thu, 23 Feb 2006 12:53:28 -0000, remark <38267@users.rsdn.ru> wrote:
> Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно?
Никак.
Для решения этой задачи хорошо подходят исключения, так как их нельзя случайно проигнорировать.
-- Maxim Yegorushkin
Posted via RSDN NNTP Server 2.0
Re[2]: Форсирование проверки возвращаемого значения
Здравствуйте, MaximE, Вы писали:
ME>On Thu, 23 Feb 2006 12:53:28 -0000, remark <38267@users.rsdn.ru> wrote:
>> Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно?
ME>Никак.
ME>Для решения этой задачи хорошо подходят исключения, так как их нельзя случайно проигнорировать.
ME>-- ME>Maxim Yegorushkin
Для решения этой задачи исключения совсем не подходят. Вызов функции может возвращать false, это не ошибка, но тем не менее проверять значение обязательно.
Пример: выполнение запроса на выборку к БД:
DBCommand dbCommand("select a, b from some_table");
while (dbCommand.Fetch()) // Выборка всех записей из запроса
{
...
// Копируем запись куда-то
}
Или выборка одной записи:
DBCommand dbCommand("select a, b from some_table");
if (!dbCommand.Fetch()) // Выборка одной записиreturn false;
...
// Обработка одной записи
R>Для решения этой задачи исключения совсем не подходят.
Почему не подходят?
Учитывая то, что мы говорим о С++, вариантов у тебя не много.
В тех ситуациях, когда обязательно надо проверить результат,
ты можешь возвращать не обычный bool, а объект
и в итоге пользоваться механизмом исключений.
А еще тебе может помочь банальное code review.
Тоже эффективный способ, чтобы проверить выполнение определенных требований к коду.
Можешь попробовать присобачить тулы для статического анализа кода.
Re[4]: Форсирование проверки возвращаемого значения
Здравствуйте, bkat, Вы писали:
B>Здравствуйте, remark, Вы писали:
R>>Для решения этой задачи исключения совсем не подходят.
B>Почему не подходят? B>Учитывая то, что мы говорим о С++, вариантов у тебя не много. B>В тех ситуациях, когда обязательно надо проверить результат, B>ты можешь возвращать не обычный bool, а объект B>и в итоге пользоваться механизмом исключений.
B>А еще тебе может помочь банальное code review. B>Тоже эффективный способ, чтобы проверить выполнение определенных требований к коду. B>Можешь попробовать присобачить тулы для статического анализа кода.
Задача именно в той постановке, в которой есть.
Уже есть дофига кода в большом количестве проектов, где используется эта функция и именно с таким описанием (как возвращающая bool).
Просмотр кода тут не подойдёт.
Изменение семантики функции нельзя делать — нельзя, что бы дофига продуктов начали пададь в местах, о которых все уже давно забыли.
Единственное, что приемлимо — если компилятор покажет места, где значение игнорировалось.
Здравствуйте, Alxndr, Вы писали:
A>Понятно, что использовать для этой цели компилятор кошернее, ну дык ты неделю будешь думать, как это реализовать (а потом все равно напишешь скрипт ).
Если это действительно критично, я бы и скрипту не доверил.
Мало ли какие ситуации в коде, а если скрипт с ошибкой,
то можно критичное место автоматически проигнорировать.
Здравствуйте, remark, Вы писали:
R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>Как ни странно на форуме ничего похожего не нашёл...
В подобной постановке задача просто некорректна и не решаема. Иными словами, Вы пытаетесь заставить автора вызывающего кода проверить значение, возвращаемое функцией. Это можно сделать лишь на уровне языка программирования и компилятора. Сама же функция не может отвечать за то, как ее используют. Грубо говоря, функция — это "кирпич", из которого автор вызывающего кода строит свой "дом". Но в реальности Вы же не можете заставить кирпич проверять, корректно ли спроектирован дом.
На мой взгляд, более продуктивно поговорить о проблемах, из-за которых Вы хотите внести такую проверку, и попробовать найти для них другое решение.
Здравствуйте, bkat, Вы писали:
B>Здравствуйте, Alxndr, Вы писали:
A>>Понятно, что использовать для этой цели компилятор кошернее, ну дык ты неделю будешь думать, как это реализовать (а потом все равно напишешь скрипт ).
B>Если это действительно критично, я бы и скрипту не доверил.
Если это действительно критично И объем работы большой И делать это придется не один раз — я выбираю автоматический инструмент.
Ты доверяешь компилятору?
B>Мало ли какие ситуации в коде, а если скрипт с ошибкой, B>то можно критичное место автоматически проигнорировать.
Инструменты надо тестировать.
Re[8]: Форсирование проверки возвращаемого значения
Здравствуйте, Alxndr, Вы писали:
B>>Мало ли какие ситуации в коде, а если скрипт с ошибкой, B>>то можно критичное место автоматически проигнорировать.
A>Инструменты надо тестировать.
Понятно что надо...
В общем это уже офтопик, который видимо
перейдет в обсуждение требований на этот самый скрипт.
По сути же я с тобой согласен.
Re[5]: Форсирование проверки возвращаемого значения
534 Ignoring return value of function 'Symbol' (compare with
Location) -- A function that returns a value is called
just for side effects as, for example, in a statement by
itself or the left-hand side of a comma operator. Try:
(void) function(); to call a function and ignore its
return value. See also the fvr, fvo and fdr flags in
Section 5.5 Flag Options.
Re[6]: Форсирование проверки возвращаемого значения
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, remark, Вы писали:
R>>Единственное, что приемлимо — если компилятор покажет места, где значение игнорировалось.
A>Объясни, почему не подходит внешний инструмент, запускаемый сразу после компиляции?
Проекты не мои, проектов много, я не могу для этих проектов запускать скрипты и т.д.
Здравствуйте, bkat, Вы писали:
B>Здравствуйте, Alxndr, Вы писали:
B>>>Мало ли какие ситуации в коде, а если скрипт с ошибкой, B>>>то можно критичное место автоматически проигнорировать.
A>>Инструменты надо тестировать.
B>Понятно что надо... B>В общем это уже офтопик, который видимо B>перейдет в обсуждение требований на этот самый скрипт.
B>По сути же я с тобой согласен.
Поддерживаю, что инструменты для автоматической проверки кода — это полезно. Особенно, если они проверяют и другие вещи.
оффтоп: меня поразили возможности IntelliJ Idea в этой области — вплоть до проверки цикломатической (по-моему так это называется) сложности функций. И всё это встроено прямо в IDE.
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Здравствуйте, remark, Вы писали:
R>>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>>Как ни странно на форуме ничего похожего не нашёл...
КЛ>В подобной постановке задача просто некорректна и не решаема. Иными словами, Вы пытаетесь заставить автора вызывающего кода проверить значение, возвращаемое функцией. Это можно сделать лишь на уровне языка программирования и компилятора. Сама же функция не может отвечать за то, как ее используют. Грубо говоря, функция — это "кирпич", из которого автор вызывающего кода строит свой "дом". Но в реальности Вы же не можете заставить кирпич проверять, корректно ли спроектирован дом.
В 90 году было так
Но теперь я могу заставить не компилироваться, где наоборот проверяется возвращаемое значение функции.
Или заставить не компилироваться присваивание переменной long результата функции, которая возвращает int.
Или определить для чего используют результат operator[] — для того, что бы присвоить ему что-то, или что бы присвоить его чему-то.
Одним словом, язык с++ гораздо более мощный, чем Вы представляете.
КЛ>На мой взгляд, более продуктивно поговорить о проблемах, из-за которых Вы хотите внести такую проверку, и попробовать найти для них другое решение.
Проблемы всё те же — забывчивость и невнимательность человека
Здравствуйте, igna, Вы писали:
I>Здравствуйте, remark, Вы писали:
R>>Проекты не мои, проектов много, я не могу для этих проектов запускать скрипты и т.д.
I>Вот оно как! Тогда предположим, будто C++ позволяет сделать так, чтобы:
I>
I>bool some_func();
I>if (some_func()); // компилируется
I>bool result = some_func(); // компилируется
I>some_func(); // не должно компилироваться
I>
I>Немаловероятно, что после первой неудачной попытки откомпилировать программу пользователь some_func сделает так:
I>
I>if (some_func())
I> do_the_same_as_yesterday();
I>else
I> ; // HANDLE THIS CASE LATER!!!
I>
I>Тем более, если проект использующий some_func завершен.
И к чему ты всё это?
А если кидать исключение? То что?
Добавят: catch (...){}
Только это ещё хуже, т.к. места, где это надо добавить выявяться только после падения программы.
Я же не говорил форсировать корректную обработку ошибки, я сказал — форсировать хотя бы проверку результата функции.
Если человек напишет: I>
I>if (some_func())
I> do_the_same_as_yesterday();
I>else
I> ; // HANDLE THIS CASE LATER!!!
I>
То возможно он задумается, что в строчке HANDLE THIS CASE LATER!!! его программа будет падать.
Здравствуйте, remark, Вы писали:
R>Пример: выполнение запроса на выборку к БД: R>
R>DBCommand dbCommand("select a, b from some_table");
R>while (dbCommand.Fetch()) // Выборка всех записей из запроса
R>{
R>...
R>// Копируем запись куда-то
R>}
R>
R>Или выборка одной записи:
R>
R>DBCommand dbCommand("select a, b from some_table");
R>if (!dbCommand.Fetch()) // Выборка одной записи
R> return false;
R>...
R>// Обработка одной записи
R>
, никаких. То есть Вы сами себе ответили, что Вам нужен анализатор кода — старый добрый lint, который как раз и принято ругать за то, что он диагностирует игнорирование возвращаемого значения функции printf. Но и этот вариант Вам почему-то не подходит
Здравствуйте, remark, Вы писали:
R>Или заставить не компилироваться присваивание переменной long результата функции, которая возвращает int.
Это не только некорректно по отношению к коллегам, использующим Ваш код, но еще и неправильно. Если программист решил преобразовать int к long'у, значит это ему для чего-то понадобилось. Изнутри (из своей функции) Вы не можете понять, правильное ли это преобразование или просто описка. Такой вывод можно сделать только путем анализа кода, вызывающего Вашу функцию.
R>Проблемы всё те же — забывчивость и невнимательность человека
Эти проблемы НЕ решаются с помощью "хитроумных" (это слово намеренно я беру в кавычки) трюков. Эти проблемы решаются с помощью стандартов и процедур. Они включают:
1) Стандарты на оформление исходного кода (coding rules).
2) Контроль качества (с помощью code review, путем использования специальных программ, анализирующих код).
R>>>bool result = some_func(); // компилируется
R>>>some_func(); // не должно компилироваться
R>>>
АТ>>Не вижу причин почему последнее не должно компилироваться. Будет оно прекрасно компилироваться.
ПК>Автор вопроса как раз хочет сделать так, чтобы оно не компилировалось.
Я понимаю. Мой ответ был задуман, как ответ на соообщение elcste, где он предлагает вариант с #define. Т.е. я имел в виду, что не вижу причин, почему последнее не должно компилироваться в контексте
#define some_func() int (some_func())
Но по ошибке я прицепил свой ответ не к тому сообщению.
Best regards,
Андрей Тарасевич
Re[4]: Форсирование проверки возвращаемого значения
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>>>Не вижу причин почему последнее не должно компилироваться. Будет оно прекрасно компилироваться.
Не компилируется, если вот так:
int main()
{
bool some_func();
#define some_func() int (some_func())
if (some_func()); // компилируетсяbool result = some_func(); // компилируется
some_func(); // не должно компилироваться
}
VC++ 7.1:
test.cpp(8) : error C2556: 'int some_func(void)' : overloaded function differs only by return type from 'bool some_func(void)'
test.cpp(3) : see declaration of 'some_func'
test.cpp(8) : error C2371: 'some_func' : redefinition; different basic types
test.cpp(3) : see declaration of 'some_func'
g++ 3.4.4:
test.cpp: In function `int main()':
test.cpp:8: error: new declaration `int some_func()'
test.cpp:3: error: ambiguates old declaration `bool some_func()'
Вряд ли вышеприведенное полезно, но VC++ 7.1 выдает ошибку и при объявлении some_func на уровне файла:
bool some_func();
#define some_func() int (some_func())
int main()
{
if (some_func()); // компилируетсяbool result = some_func(); // компилируется
some_func(); // не должно компилироваться
}
, что может пригодиться на практике.
Re[4]: Форсирование проверки возвращаемого значения
Здравствуйте, Pavel Chikulaev, Вы писали:
PC>Здравствуйте, remark, Вы писали:
R>>Пример: выполнение запроса на выборку к БД: R>>
R>>DBCommand dbCommand("select a, b from some_table");
R>>while (dbCommand.Fetch()) // Выборка всех записей из запроса
R>>{
R>>...
R>>// Копируем запись куда-то
R>>}
R>>
R>>Или выборка одной записи:
R>>
R>>DBCommand dbCommand("select a, b from some_table");
R>>if (!dbCommand.Fetch()) // Выборка одной записи
R>> return false;
R>>...
R>>// Обработка одной записи
R>>
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Здравствуйте, remark, Вы писали:
R>>Или заставить не компилироваться присваивание переменной long результата функции, которая возвращает int. КЛ>Это не только некорректно по отношению к коллегам, использующим Ваш код, но еще и неправильно. Если программист решил преобразовать int к long'у, значит это ему для чего-то понадобилось. Изнутри (из своей функции) Вы не можете понять, правильное ли это преобразование или просто описка. Такой вывод можно сделать только путем анализа кода, вызывающего Вашу функцию.
Это спорный вопрос — правильно это или нет. В любом случае я не писал, что я так делаю. Я написал, что такие вещи можно делать.
R>>Проблемы всё те же — забывчивость и невнимательность человека КЛ>Эти проблемы НЕ решаются с помощью "хитроумных" (это слово намеренно я беру в кавычки) трюков. Эти проблемы решаются с помощью стандартов и процедур. Они включают:
КЛ>1) Стандарты на оформление исходного кода (coding rules). КЛ>2) Контроль качества (с помощью code review, путем использования специальных программ, анализирующих код).
Ну не знаю, не знаю. Мне, например, легче применить такой "хитроумных" трюк, как сделать конструктор класса закрытым, что бы убедиться, что пользователь не будет явно создавать экземпляры, чем просматривать весь код и смотреть самому, что кто-то не создаёт экземпляры класса
Или ты тут со мной не согласен? Ты считаешь, такие вещи надо выносить в стандарт кодирования и искать с помощью code review.
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно?
E>Попробуйте формализовать задачу. Что считать "проверкой"? И какие изменения для этого можно вносить в код? Судя по тому, что сказано здесь
, никаких. То есть Вы сами себе ответили, что Вам нужен анализатор кода — старый добрый lint, который как раз и принято ругать за то, что он диагностирует игнорирование возвращаемого значения функции printf. Но и этот вариант Вам почему-то не подходит
if (some_func());
while (some_func());
bool b = some_func();
Ну в общем — приведение к bool.
Изменения можно вносить такие, что бы продолжало компилироваться масса старого кода, который выглядит примерно так:
if (some_func());
while (some_func());
bool b = some_func();
Анализатор кода не подходит так как проекты не мои.
+ имеется чисто академический интерес, можно ли такое сделать средствами компилятора. Всё таки согласись, форсирование правильного кода средствами компилятора лучше внешних утилит.
R>>if (some_func()); // компилируется
R>>bool result = some_func(); // компилируется
R>>some_func(); // не должно компилироваться
E>
Вот это очень зянятно — первое реальное решение.
Правда мне оно опять не подходит
Решение не универсальное — нужно, что бы оно работало и для методов классов. Я не писал, что речь идёт о методе, т.к. честно говоря надеялся на решение в немного другом ключе.
Здравствуйте, remark, Вы писали:
R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>Как ни странно на форуме ничего похожего не нашёл...
Предлагаю такую методу выявления списка мест, где игнорится возвращаемое значение твоего метода.
1)
Пишешь хеедр:
#ifdef __CHECK_STEP_1__
class CCheckResult {
public:
CCheckResult( bool f ) data( f ) {}
private:
bool data;
~CCheckResult() {}
};
#else
#ifdef __CHECK_STEP_2__
class CCheckResult {
private:
bool data;
~CCheckResult() {}
CCheckResult( bool f ) data( f ) {}
};
#else
typedef bool CCheckResult;
#endif
#endif
2)
Меняешь прототип твоего метода, чтобы он возвращаал CCheckResult
3) Компилишь последователоьно с макросом __CHECK_STEP_1__ и __CHECK_STEP_2__, оба раза сохраняя лог компиляции
4) Сравниваешь логи. Те места, где к ошибке на шаге 1 не добавилась ошибк ана шаге два -- очень подозрительные
5) Компилируешь всё вовсе без макросов __CHECK_STEP_1__ и __CHECK_STEP_2__
Или такой подход тебе тоже не катаит
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Форсирование проверки возвращаемого значения
Здравствуйте, igna, Вы писали:
I>Не компилируется, если вот так:
I>
I>int main()
I>{
I> bool some_func();
I> #define some_func() int (some_func())
I> if (some_func()); // компилируется
I> bool result = some_func(); // компилируется
I> some_func(); // не должно компилироваться
I>}
I>
I>VC++ 7.1: I>
I>test.cpp(8) : error C2556: 'int some_func(void)' : overloaded function differs only by return type from 'bool some_func(void)'
I> test.cpp(3) : see declaration of 'some_func'
I>test.cpp(8) : error C2371: 'some_func' : redefinition; different basic types
I> test.cpp(3) : see declaration of 'some_func'
I>g++ 3.4.4: I>
I>test.cpp: In function `int main()':
I>test.cpp:8: error: new declaration `int some_func()'
I>test.cpp:3: error: ambiguates old declaration `bool some_func()'
I>Вряд ли вышеприведенное полезно, но VC++ 7.1 выдает ошибку и при объявлении some_func на уровне файла:
I>
I>bool some_func();
I>#define some_func() int (some_func())
I>int main()
I>{
I> if (some_func()); // компилируется
I> bool result = some_func(); // компилируется
I> some_func(); // не должно компилироваться
I>}
I>
I>, что может пригодиться на практике.
Помоему здесь используется недостаточный интеллект синтаксического анализатора применяемых компиляторов, которые не смогли догадаться, что "int (some_func());" не объявление функции, а её использование. Так можно нарваться на более интеллектуального товарища, который догадается об этом и ругаться не будет.
При этом, будя в полной уверенности в решенной проблеме, можно насовершать лишних ошибок.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>>Как ни странно на форуме ничего похожего не нашёл...
E>Предлагаю такую методу выявления списка мест, где игнорится возвращаемое значение твоего метода.
E>2) E>Меняешь прототип твоего метода, чтобы он возвращаал CCheckResult
E>3) Компилишь последователоьно с макросом __CHECK_STEP_1__ и __CHECK_STEP_2__, оба раза сохраняя лог компиляции
E>4) Сравниваешь логи. Те места, где к ошибке на шаге 1 не добавилась ошибк ана шаге два -- очень подозрительные
E>5) Компилируешь всё вовсе без макросов __CHECK_STEP_1__ и __CHECK_STEP_2__
E>Или такой подход тебе тоже не катаит
Тоже не покатит
Слишком сложно — я не буду проделывать это с десятками больших проектов.
Тем более это не удовлетворяет мой академический интерес...
Здравствуйте, remark, Вы писали:
R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>Как ни странно на форуме ничего похожего не нашёл...
Я не совсем понимаю одну вещь. Почему так плохо игнорировать возвращаемое значение твоей функции? Я так думаю, что это обозначает, что у неё плохая семантика
Не приоткроешь карты?
Я бы, в описанной тобой ситуации, следовал бы плану из трёх пунктов
1) Организовал бы какие-то rt-средства контроля. Так, чтобы у пользователей была возможность что-то где-то включить, или открыть какой-то лог и посмотреть есть ли у них проблемы
2) Разработал ьы альтернативный интерфейс к сервису, в котором бы подобная проблема просто не возникала бы. И рекомендовал бы использовать именно его
3) Старый бы интерфейс объявил устаревшим и оставленным для совместимости. Возможно озаботился бы появлением соответсвующего предупреждения при компиляции кода, апеллирующего к старому интерфейсу
Ну и последнее, но главное.
Мне так каежтся, что трюки -- это вообще плохо, потому что непонятно. Комментарий, какие-то простые assert's намного эффективнее, если рассматриватьпрограммирование, как производственный процесс
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>>Как ни странно на форуме ничего похожего не нашёл...
E>Я не совсем понимаю одну вещь. Почему так плохо игнорировать возвращаемое значение твоей функции? Я так думаю, что это обозначает, что у неё плохая семантика E>Не приоткроешь карты? E> E>Я бы, в описанной тобой ситуации, следовал бы плану из трёх пунктов
E>1) Организовал бы какие-то rt-средства контроля. Так, чтобы у пользователей была возможность что-то где-то включить, или открыть какой-то лог и посмотреть есть ли у них проблемы
E>2) Разработал ьы альтернативный интерфейс к сервису, в котором бы подобная проблема просто не возникала бы. И рекомендовал бы использовать именно его
E>3) Старый бы интерфейс объявил устаревшим и оставленным для совместимости. Возможно озаботился бы появлением соответсвующего предупреждения при компиляции кода, апеллирующего к старому интерфейсу E> E>Ну и последнее, но главное. E>Мне так каежтся, что трюки -- это вообще плохо, потому что непонятно. Комментарий, какие-то простые assert's намного эффективнее, если рассматриватьпрограммирование, как производственный процесс
Вот пример — выборка записей из БД:
Можно выбирать все записи:
DBCommand dbCommand("select a, b from some_table");
while (dbCommand.Fetch()) // Выборка всех записей из запроса
{
...
// Копируем запись куда-то
}
Можно выбирать одну запись:
DBCommand dbCommand("select a, b from some_table");
if (!dbCommand.Fetch()) // Выборка одной записиreturn false;
...
// Обработка одной записи
Зачастую при выборке одной записи делается просто:
DBCommand dbCommand("select a, b from some_table");
dbCommand.Fetch(); // Выборка одной записи
Из соображений "ну эта запись там обязательно должна быть", "куда ж ей деться". Что-то типа "ну памяти всегда хватает" или "маловероятно, что вызов этой функции провалится, поэтому я никогда не проверяю результат".
Проблема в том, что если я предоставляю интерфейс для "while (dbCommand.Fetch())", то получается, что им автоматически можно пользоваться и как в последнем варианте.
Я бы не сказал, что тут плохой дизайн или плохая семантика. Новый интерфейс нет смысла придумывать — этот вполне адекватный.
О каких трюках ты говоришь — пока нет никакого решения.
R>Я бы не сказал, что тут плохой дизайн или плохая семантика. Новый интерфейс нет смысла придумывать — этот вполне адекватный. R>О каких трюках ты говоришь — пока нет никакого решения.
R>
Я бы сказал, что проблема чисто умозрительная
Адекватное решение, как мне кажется, в этом случае -- итератор
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Я бы не сказал, что тут плохой дизайн или плохая семантика. Новый интерфейс нет смысла придумывать — этот вполне адекватный. R>>О каких трюках ты говоришь — пока нет никакого решения.
R>>
E>Я бы сказал, что проблема чисто умозрительная
E>Адекватное решение, как мне кажется, в этом случае -- итератор
А это что по-твоему? Итератор чистой воды!
Если тебе нужна запись в базисе {begin, end, ++}, то читай
конструктор DBCommand — begin()
Fetch() — operator++ с одновременным сравнением с end()
Здравствуйте, remark, Вы писали:
R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>Как ни странно на форуме ничего похожего не нашёл...
Читая A Policy-Based Observer(I), наткнулся на забавное расширение gcc:
Здравствуйте, Angler, Вы писали:
A>Здравствуйте, remark, Вы писали:
R>>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>>Как ни странно на форуме ничего похожего не нашёл...
A>Читая A Policy-Based Observer(I), наткнулся на забавное расширение gcc: A>
A>__attribute__((warn_unused_result));
A>
Прикольно. Я так понимаю, что это именно то, что мне надо. Если ещё с помощью pragma поднять уровень этого варнинга до error'а.
... жаль, что я работаю на msvc... Странно, что m$ не сделала чего-то подобного в __declspec
АТ>>>Не вижу причин почему последнее не должно компилироваться. Будет оно прекрасно компилироваться.
ПК>>Автор вопроса как раз хочет сделать так, чтобы оно не компилировалось.
АТ>Я понимаю. Мой ответ был задуман, как ответ на соообщение elcste, где он предлагает вариант с #define. Т.е. я имел в виду, что не вижу причин, почему последнее не должно компилироваться в контексте
АТ>#define some_func() int (some_func())
Если я правильно понимаю, в этом случае программа должна быть ill-formed в соответствии с 13.1/1-2.
Re[5]: Форсирование проверки возвращаемого значения
Здравствуйте, remark, Вы писали:
R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно? R>Как ни странно на форуме ничего похожего не нашёл...
R>Например:
R>
R>bool some_func();
R>if (some_func()); // компилируется
R>bool result = some_func(); // компилируется
R>some_func(); // не должно компилироваться
R>
Почемубы не параметр по ссылке?
void some_func(bool & result);
или
class Result
{
private:
bool value, isChecked;
public:
Result(bool v) : value(v), isChecked(false) { }
operator bool()
{
this->isChecked= true;
return this->value;
}
~Result()
{
if (!isChecked) { } // чего-то там...
}
};
Result some_func();
Re[2]: Форсирование проверки возвращаемого значения