Re[3]: Форсирование проверки возвращаемого значения
От: Pavel Chikulaev Россия  
Дата: 24.02.06 12:52
Оценка:
Здравствуйте, 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>

ИМХО это ошибка дизайна.
Re: Форсирование проверки возвращаемого значения
От: elcste  
Дата: 24.02.06 15:31
Оценка: 39 (3)
Здравствуйте, remark, Вы писали:

R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно?


Попробуйте формализовать задачу. Что считать "проверкой"? И какие изменения для этого можно вносить в код? Судя по тому, что сказано здесь
Автор: remark
Дата: 24.02.06
, никаких. То есть Вы сами себе ответили, что Вам нужен анализатор кода — старый добрый lint, который как раз и принято ругать за то, что он диагностирует игнорирование возвращаемого значения функции printf. Но и этот вариант Вам почему-то не подходит
Автор: remark
Дата: 24.02.06
.

А так... какая постановка задачи, такое и решение.

R>bool some_func();

#define some_func() int (some_func())

R>if (some_func()); // компилируется

R>bool result = some_func(); // компилируется

R>some_func(); // не должно компилироваться
Re[4]: Форсирование проверки возвращаемого значения
От: bkat  
Дата: 24.02.06 15:45
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>ИМХО это ошибка дизайна.


Хм... Я бы по такому мизерному куску кода об ошибке дизайна рискнуть не решился.
Тем более пример явно тестовый

Кстати, в реальных проектах полно разных ошибок дизайна,
с которыми приходится жить.
Re: Форсирование проверки возвращаемого значения
От: Андрей Тарасевич Беларусь  
Дата: 24.02.06 18:23
Оценка: :)
Здравствуйте, remark, Вы писали:

R>Например:


R>
R>bool some_func();

R>if (some_func()); // компилируется

R>bool result = some_func(); // компилируется

R>some_func(); // не должно компилироваться
R>


Не вижу причин почему последнее не должно компилироваться. Будет оно прекрасно компилироваться.
Best regards,
Андрей Тарасевич
Re[2]: Форсирование проверки возвращаемого значения
От: Павел Кузнецов  
Дата: 24.02.06 18:59
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

R>>
R>>bool result = some_func(); // компилируется

R>>some_func(); // не должно компилироваться
R>>


АТ>Не вижу причин почему последнее не должно компилироваться. Будет оно прекрасно компилироваться.


Автор вопроса как раз хочет сделать так, чтобы оно не компилировалось.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Форсирование проверки возвращаемого значения
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 24.02.06 20:14
Оценка:
Здравствуйте, remark, Вы писали:

R>Или заставить не компилироваться присваивание переменной long результата функции, которая возвращает int.

Это не только некорректно по отношению к коллегам, использующим Ваш код, но еще и неправильно. Если программист решил преобразовать int к long'у, значит это ему для чего-то понадобилось. Изнутри (из своей функции) Вы не можете понять, правильное ли это преобразование или просто описка. Такой вывод можно сделать только путем анализа кода, вызывающего Вашу функцию.

R>Проблемы всё те же — забывчивость и невнимательность человека

Эти проблемы НЕ решаются с помощью "хитроумных" (это слово намеренно я беру в кавычки) трюков. Эти проблемы решаются с помощью стандартов и процедур. Они включают:

1) Стандарты на оформление исходного кода (coding rules).
2) Контроль качества (с помощью code review, путем использования специальных программ, анализирующих код).
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[3]: Форсирование проверки возвращаемого значения
От: Андрей Тарасевич Беларусь  
Дата: 25.02.06 02:47
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

R>>>
R>>>bool result = some_func(); // компилируется

R>>>some_func(); // не должно компилироваться
R>>>


АТ>>Не вижу причин почему последнее не должно компилироваться. Будет оно прекрасно компилироваться.


ПК>Автор вопроса как раз хочет сделать так, чтобы оно не компилировалось.


Я понимаю. Мой ответ был задуман, как ответ на соообщение elcste, где он предлагает вариант с #define. Т.е. я имел в виду, что не вижу причин, почему последнее не должно компилироваться в контексте

#define some_func() int (some_func())


Но по ошибке я прицепил свой ответ не к тому сообщению.
Best regards,
Андрей Тарасевич
Re[4]: Форсирование проверки возвращаемого значения
От: igna Россия  
Дата: 25.02.06 05:22
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>>>Не вижу причин почему последнее не должно компилироваться. Будет оно прекрасно компилироваться.


Не компилируется, если вот так:

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]: Форсирование проверки возвращаемого значения
От: remark Россия http://www.1024cores.net/
Дата: 25.02.06 09:18
Оценка:
Здравствуйте, 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>>

PC>ИМХО это ошибка дизайна.

В чём тут ошибка дизайна? Можно поконкретнее.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Форсирование проверки возвращаемого значения
От: remark Россия http://www.1024cores.net/
Дата: 25.02.06 09:25
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, remark, Вы писали:


R>>Или заставить не компилироваться присваивание переменной long результата функции, которая возвращает int.

КЛ>Это не только некорректно по отношению к коллегам, использующим Ваш код, но еще и неправильно. Если программист решил преобразовать int к long'у, значит это ему для чего-то понадобилось. Изнутри (из своей функции) Вы не можете понять, правильное ли это преобразование или просто описка. Такой вывод можно сделать только путем анализа кода, вызывающего Вашу функцию.


Это спорный вопрос — правильно это или нет. В любом случае я не писал, что я так делаю. Я написал, что такие вещи можно делать.


R>>Проблемы всё те же — забывчивость и невнимательность человека

КЛ>Эти проблемы НЕ решаются с помощью "хитроумных" (это слово намеренно я беру в кавычки) трюков. Эти проблемы решаются с помощью стандартов и процедур. Они включают:

КЛ>1) Стандарты на оформление исходного кода (coding rules).

КЛ>2) Контроль качества (с помощью code review, путем использования специальных программ, анализирующих код).


Ну не знаю, не знаю. Мне, например, легче применить такой "хитроумных" трюк, как сделать конструктор класса закрытым, что бы убедиться, что пользователь не будет явно создавать экземпляры, чем просматривать весь код и смотреть самому, что кто-то не создаёт экземпляры класса
Или ты тут со мной не согласен? Ты считаешь, такие вещи надо выносить в стандарт кодирования и искать с помощью code review.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Форсирование проверки возвращаемого значения
От: remark Россия http://www.1024cores.net/
Дата: 25.02.06 09:36
Оценка:
Здравствуйте, elcste, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно?


E>Попробуйте формализовать задачу. Что считать "проверкой"? И какие изменения для этого можно вносить в код? Судя по тому, что сказано здесь
Автор: remark
Дата: 24.02.06
, никаких. То есть Вы сами себе ответили, что Вам нужен анализатор кода — старый добрый lint, который как раз и принято ругать за то, что он диагностирует игнорирование возвращаемого значения функции printf. Но и этот вариант Вам почему-то не подходит
Автор: remark
Дата: 24.02.06
.



Под проверкой в данном контексте я понимаю:
if (some_func());
while (some_func());
bool b = some_func();


Ну в общем — приведение к bool.

Изменения можно вносить такие, что бы продолжало компилироваться масса старого кода, который выглядит примерно так:
if (some_func());
while (some_func());
bool b = some_func();



Анализатор кода не подходит так как проекты не мои.
+ имеется чисто академический интерес, можно ли такое сделать средствами компилятора. Всё таки согласись, форсирование правильного кода средствами компилятора лучше внешних утилит.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Форсирование проверки возвращаемого значения
От: remark Россия http://www.1024cores.net/
Дата: 25.02.06 09:40
Оценка:
Здравствуйте, elcste, Вы писали:

E>
R>>bool some_func();
E>

E>
E>#define some_func() int (some_func())
E>

E>
R>>if (some_func()); // компилируется

R>>bool result = some_func(); // компилируется

R>>some_func(); // не должно компилироваться
E>



Вот это очень зянятно — первое реальное решение.

Правда мне оно опять не подходит
Решение не универсальное — нужно, что бы оно работало и для методов классов. Я не писал, что речь идёт о методе, т.к. честно говоря надеялся на решение в немного другом ключе.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Возможно тоже не подойдёт, но...
От: Erop Россия  
Дата: 25.02.06 12:44
Оценка:
Здравствуйте, 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]: Форсирование проверки возвращаемого значения
От: michus Россия  
Дата: 25.02.06 13:03
Оценка:
Здравствуйте, 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());" не объявление функции, а её использование. Так можно нарваться на более интеллектуального товарища, который догадается об этом и ругаться не будет.

При этом, будя в полной уверенности в решенной проблеме, можно насовершать лишних ошибок.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Возможно тоже не подойдёт, но...
От: remark Россия http://www.1024cores.net/
Дата: 25.02.06 13:04
Оценка:
Здравствуйте, 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>Или такой подход тебе тоже не катаит



Тоже не покатит
Слишком сложно — я не буду проделывать это с десятками больших проектов.
Тем более это не удовлетворяет мой академический интерес...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: Форсирование проверки возвращаемого значения
От: igna Россия  
Дата: 25.02.06 13:10
Оценка: +2
Здравствуйте, michus, Вы писали:

M> ... не смогли догадаться, что "int (some_func());" не объявление функции, а её использование.


И не должны. Даже должны не догадываться, все что может быть объявлением, есть объявление.
Re[7]: Форсирование проверки возвращаемого значения
От: michus Россия  
Дата: 25.02.06 14:04
Оценка:
Здравствуйте, igna, Вы писали:

I>И не должны. Даже должны не догадываться, все что может быть объявлением, есть объявление.


Верно [dcl.ambig.res]
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Что бы я сделал на практике?
От: Erop Россия  
Дата: 25.02.06 15:02
Оценка:
Здравствуйте, remark, Вы писали:

R>Как на стадии компиляции форсировать проверку возвращаемого значения функции? Или это не возможно?

R>Как ни странно на форуме ничего похожего не нашёл...

Я не совсем понимаю одну вещь. Почему так плохо игнорировать возвращаемое значение твоей функции? Я так думаю, что это обозначает, что у неё плохая семантика
Не приоткроешь карты?


Я бы, в описанной тобой ситуации, следовал бы плану из трёх пунктов

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

2) Разработал ьы альтернативный интерфейс к сервису, в котором бы подобная проблема просто не возникала бы. И рекомендовал бы использовать именно его

3) Старый бы интерфейс объявил устаревшим и оставленным для совместимости. Возможно озаботился бы появлением соответсвующего предупреждения при компиляции кода, апеллирующего к старому интерфейсу


Ну и последнее, но главное.
Мне так каежтся, что трюки -- это вообще плохо, потому что непонятно. Комментарий, какие-то простые assert's намного эффективнее, если рассматриватьпрограммирование, как производственный процесс
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Что бы я сделал на практике?
От: remark Россия http://www.1024cores.net/
Дата: 25.02.06 15:58
Оценка:
Здравствуйте, 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())", то получается, что им автоматически можно пользоваться и как в последнем варианте.


Я бы не сказал, что тут плохой дизайн или плохая семантика. Новый интерфейс нет смысла придумывать — этот вполне адекватный.
О каких трюках ты говоришь — пока нет никакого решения.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Что бы я сделал на практике?
От: Erop Россия  
Дата: 25.02.06 16:05
Оценка:
Здравствуйте, remark, Вы писали:


R>Я бы не сказал, что тут плохой дизайн или плохая семантика. Новый интерфейс нет смысла придумывать — этот вполне адекватный.

R>О каких трюках ты говоришь — пока нет никакого решения.

R>


Я бы сказал, что проблема чисто умозрительная

Адекватное решение, как мне кажется, в этом случае -- итератор
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.