LINUX.ORG.RU

Любовь к C++. Как бороться с собственной невнимательностью.


1

2

Как я люблю этот язык. Всего лишь из-за одного лишнего символа в описании членов класса я убил на отдладку более 6 часов.

/** @brief Задание для отправки много авторок */
class CCrShareSender : public boost::enable_shared_from_this<CCrShareSender> {
public:
	CCrShareSender(QList<CrShare>& a_shares, CAdminWidget* a_widget);
	~CCrShareSender();
	/** @brief Отправить все */
	sequence::_void sendAll();
private:
	CTaskModel m_model;					///< Модель вывода
	QList<CrShare>& m_shares;			///< Оставшиеся шары

В последней строчку случайно появился &.

А как вы ловите такие ошибки? Кроме долгого вхождения в ДЗЕН

★★★★

за годы математики в универе выработалась специфичная внимательность

TERRANZ ★★★★
()
Ответ на: комментарий от staseg

Я там ссылку не хотел. «&» попал как-то случайно. Смысл то во всем это как раз и было утащить QList<CrShare> со стека в кучу, чтоб можно было выйти из функи.

Обратил бы сразу внимание на то, что там ссылка - исправил бы за 5 сек.

Хотя за одно и досадную оплошность допустил, в конструкторе первый аргумент должен быть const, тогда и свалилось бы все. Хотя это не спасет от в случае, если похожая ошибка будет с const объектом.

namezys ★★★★
() автор топика
Ответ на: комментарий от namezys

Ну вообще валгринд валит эти места на раз: получишь invalid read и дальше стек вызова с указанием файлов исходников и номеров строк.

staseg ★★★★★
()

значит ты ошибся два раза - «забыл» const для параметра, а это уже не просто невнимательность

aho
()
Ответ на: комментарий от staseg

да я и без него видел что объекта нет. а деструктор не выполнялся, вот и не мог понять - куда это член класса девается

namezys ★★★★
() автор топика
Ответ на: комментарий от aho

Вот не надо. Щас пришел на работу, помедитировал 5 минут, потом глянул еще раз, увидел, что нет const, подумал, не пил ли я вчера (вроде нет), добавил его и сразу же компилятор сругался.

Но могло быть так, что мне там понадобился бы константный член, и тогда это не помогло бы

namezys ★★★★
() автор топика
Ответ на: комментарий от namezys

> Но могло быть так, что мне там понадобился бы константный член, и тогда это не помогло бы

зачем тебе мог понадобится «const QList<CrShare>» как член класса?

aho
()

Если CrShare — твой класс, то возможно поможет запрет конструктора копирования в нём

class CrShare
{
  ...
private:
   CrShare (const CrShare &);
}
ringill
()

Всего лишь из-за одного лишнего символа

появился &

Это не просто символ какой-то там. ;-)

Deleted
()
Ответ на: комментарий от aho

> зачем тебе мог понадобится «const QList<CrShare>» как член класса?

Хранить список. Класс этот создается на куче, отрабатывает некоторое действие (идет по списку и общается асинхронно с сервером), а потом уже уделяет себя сам (скажем так для краткости)

namezys ★★★★
() автор топика

Не нравится С++ — не пользуйся С++. Меняй работу и так далее. А то развелось плюсовых мазохистов. Ненавидят С++, но пишут и пишут на С++, пишут и пишут на С++, как будто товарищ Бьярн его мёдом намазал.

anonymous
()
Ответ на: комментарий от anonymous

Я же озаглавил тему - любовь :)

namezys ★★★★
() автор топика
Ответ на: комментарий от namezys

Метод основан на на чтении своего собсвенного кода. git bisect находит коммит, в котором твой баг, а потом просто смотришь diff и думаешь. В лучшем случае часы могли бы сократится до минут.

Хотя это всё зависит от многого. На сколько большой коммит например, или сложность воспроизведения бага. И т.д. Хороший, годный метод.

nanoo_linux
()
Ответ на: комментарий от nanoo_linux

Весь кусок - 70 строк. коммит - это как раз весь кусок (по отдельности он не имеет смысл)

namezys ★★★★
() автор топика
Ответ на: комментарий от nanoo_linux

Тем более я знаю, когда появился баг. В общем-то не плохой метод, если баг появился после некоторого времени работы

namezys ★★★★
() автор топика
Ответ на: комментарий от namezys

тогда только тренировать внимательность.

waker ★★★★★
()
Ответ на: комментарий от namezys

> Я там ссылку не хотел. «&» попал как-то случайно.

QList<CrShare>& a_shares

QList<CrShare>& m_shares

Как вариант защиты от подобных ошибок - отключи в редакторе функции copy и paste

nozh
()

Зачем @brief каждый раз писать? Там же можно настроить, чтобы первое предложение само делалось brief'ом.

Obey-Kun ★★★★★
()

> А как вы ловите такие ошибки?

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

gandjubas
()
Ответ на: комментарий от gandjubas

> супер-мега производительность

Имелась в виду скорость работы программы.

gandjubas
()
Ответ на: комментарий от Obey-Kun

это фигня быстро замечается самые сложные это «тихие» перезаписи за пределами буферов а потом вылеты совсем в других местах вот где посидеть приходится

anonymous
()

Именно об этом я всегда говорил. Мощь плюсов направлена в разные стороны, в т.е. против программиста.

svu ★★★★★
()
Ответ на: комментарий от anonymous

в одном проекте сейчас падает где то в недрах системных библиотек параметры из моего кода передаются корректные внутри системной библиотеки происходит еще с десяток вызовов и потом падает у меня сейчас одно предположение где то совсем стронний код перезаписывает не принадлжежащую ему память а вскрывается все намного позже и совсем не там этот баг так и висит не отлаженный

anonymous
()
Ответ на: комментарий от svu

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

anonymous
()

хорошо что я уже не пишу на этом кошмаре.

Common Lisp в связке с C выносят сабжевый недоязычек в гумно.

anonymous
()
Ответ на: комментарий от anonymous

> как будто товарищ Бьярн его мёдом намазал

Этот товарищь оббегал все комитеты и инстанции моля и ползая на коленях, что-бы его недоязычек приняли в стандарт.

anonymous
()
Ответ на: комментарий от Obey-Kun

Зачем @brief каждый раз писать? Там же можно настроить, чтобы первое предложение само делалось brief'ом.

и второй @brief достоин пера К.О., как минимум

shty ★★★★★
()
Ответ на: комментарий от namezys

эм, задумался про гном, немного недописал: TDD (не test-first и не test-last) во все поля, мне весьма здорово помогает сохранять контроль, не панацея конечно, но процентов 70 ошибок позволяет избежать

shty ★★★★★
()
Ответ на: комментарий от gandjubas

Указатели в принимающей функции надо всегда (!) проверять на валидность, чего не требуют ссылки.

anonymous
()
Ответ на: комментарий от namezys

> да не хотел я его использовать. поставил случайно &

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

gandjubas
()
Ответ на: комментарий от anonymous

Указатели в принимающей функции надо всегда (!) проверять на валидность, чего не требуют ссылки.


#define srt(PTR) if(!(PTR)){ throw std::exception(#PTR); }

или типа того, с вас не убудет, если вы напишите srt(p1 && p2 /*... */); в начале функции

gandjubas
()
Ответ на: комментарий от yoghurt

> Проверка с нулем ЕМНИП самая быстрая проверка, не?

В любом случае это ожидание ошибку. А когда пишешь с ссылкой - всегда считаешь, что она валидная

namezys ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.