LINUX.ORG.RU

По-настоящему важный вопрос

 ,


1

3

Куда вы ставите звёздочки и амперсанды при объявлении/инициализации указателей и ссылок, и почему?

  1. T* name, T& name
  2. T * name, T & name
  3. T *name, T &name
  4. Я талиб, я везде использую передачу по значению

P.S. Это не тупой наброс, мне правда интересно кто как делает, может есть весомые причины делать так или иначе, которые открываются с опытом.

Ответ на: комментарий от firkax

В моём случае проблему решил -fanalyzer, который нашел это и еще кучу всего.

Оказывается, этот код возник в результате перетасовывания функций при смене API одного из классов.

wandrien ★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от firkax

Кстати, PCMan условия входа в цикл перебора по итератору обычно писал вот с таким оформлением:

    if(gtk_tree_model_get_iter_first(model, &it)) do
    {
        ....
    }
    while(gtk_tree_model_iter_next(model, &it));

Осуждаешь/одобряешь?

wandrien ★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от wandrien

Я бы возможно заменил на for() и возможно переделал реализацию gtk_tree_model_get_iter_first() и gtk_tree_model_iter_next() чтобы они лучше в это укладывались. Но в целом ничего страшного.

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

Я и не знал про этот ключ. Для интереса скомпилировал с ним движок колоночной бд который делаю - он довольно долго висел но ничего не нашёл. До этого единственная автоматизация против багов была в виде -Wreturn-type -Wpointer-sign -Wsign-compare -Wshadow -Wpointer-arith -Wimplicit -Wformat -Werror -Wno-parentheses -Wuninitialized.

То, что он долго работает - однозначно минус, а ничего нового по сравнению с этим ничего не замедляющим списком варнингов он не находит. Хотя наверно стоит иногда с ним запускать сборку на всякий случай.

Проверил библиотеку - тоже ничего.

Проверил fwm - нашлось double-free которое оказалось ложным срабатыванием - он запутался в простом цикле

for(j=0; j<n; j++) free(l[j].list);
посчитав что вторая и третья его итерации освобождают одно и то же (и это при том что в его трассировке значение для n было неизвестным и не могло быть известным).

Проверил ещё один проект, старый из 2015 - опять то же самое

  for(i=0; i<fl->ccount; i++) {
    flc = fl->clist[i];
    assert(flc!=NULL);
    free(flc);
  }
double-free из второй и третьей итерации цикла. Что-то уже не уверен в его полезности. (хотя это gcc 10.2.1 из дебиана, может там старый и бажный анализатор)

И кажется, он не видит всякие double-free в новом коде из-за того что я обычно не использую дефолтные функции аллокатора а использую обёртку. Не знаю, можно ли их туда дописать.

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

Кстати я надеюсь эта функция не вызывается каждый раз при рисовании экрана. По-хорошему этот счётчик надо засунуть внутрь какой-то структуры и там динамически обновлять при изменении is_selected какого-нить элемента. Либо, если это затруднительно из-за мультитред мютексов, ставить флаг «надо пересчитать» но число хранить всё равно в структуре. А то будут лаги если выбрано 100к файлов.

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

У меня он нашел несколько потенциальных разыменований нуля и одно ложное срабатывание: По-настоящему важный вопрос (комментарий)

И штуки 4 ошибок в модификаторах printf().

Также нашел потенциально утёкший дескриптор, но я еще не смотрел код, что он там накопал.

gcc 13 у меня. Тут вроде доработали этот анализатор.

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

Ошибки в printf ищутся -Wformat. Но у меня тоже не ищутся т.к. формативание своей функцией и немного отличающимся от printf форматом. Прописать свои спецификаторы в этот проверяльщик кажется нельзя, ни в -Wformat ни в анализатор, а было бы полезно да.

Тут вроде доработали этот анализатор.

Но он всё ещё перепутывает err=NULL и fpath=NULL. Надеюсь кстати это не достоверное отражение того, как gcc оптимизирует код, а то вдруг это что-то из серии «вроде тут никто fpath не присваивал, зато рядом присвоили другой указатель, наверно он алиас к fpath т.к. иначе будет UB».

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

Я бы возможно заменил на for() и возможно переделал реализацию gtk_tree_model_get_iter_first() и gtk_tree_model_iter_next() чтобы они лучше в это укладывались. Но в целом ничего страшного.

for() требует делать 2 операции на каждой итерации:

for (...; делай раз; делай два)

Т.к. это вызов «неизвестно куда» и неизвестно сколько это стоит по вычислениям относительно тела цикла, в какой-то ситуации это может оказаться чувствительным.

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

Не требует.

for(value=iter_first(list,&it); value; value=iter_next(list,&it)) {
}

это то же самое что

if(value=iter_first(list,&it)) do {
} while(value=iter_next(list,&it));

но записанное в наглядном виде. Выражение «value» в середине при включённом хотя бы -O1 скорее всего никаких лишних действий выполнять не будет (вот проверил даже: https://godbolt.org/z/M7PjaWh8v - асм-код одинаковый), а при -O0 это будет незначительная разница примерно в один лишний переход за весь цикл и одну лишнюю запись из регистра в память на итерацию. Ну, если мы хотим вручную до конца всё оптимизировать то возможно if-do-while и лучше, но -O0 всё равно будет медленнее чем -O1.

В некоторых случаях, когда стартовое условие и условие следующего цикла слишком непохожи друг на друга, я вроде и сам if-do-while писал, но это было крайне редко.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от wandrien

Во, я вспомнил в чём разница, по крайней мере касательно инициализации в объявлении. В С++ нельзя объявить неинициализированный объект, он будет инициализирован дефолтным конструктором если ты не укажешь ему что-то конкретное и это явно не то что нам нужно, если планируется его инициализировать недефолтным. Отсюда идут и объявления в середине кода, когда надо создать (в локальном стеке) объект и дать его конструктору аргументы, которые мы узнали только сейчас. Ну а потом эти привычки перетекают и на не-ООП типы языка по аналогии.

В Си же объектов и RAII нет, поэтому неактуально.

firkax ★★★★★
()