LINUX.ORG.RU

Дэйтел актуален ли?

 ,


4

3

Доброго дня!

Тяжёлая книга. По весу. ;-)

Но вот сейчас пытаюсь читать в оригинале «Modern C», «21st Century C» часто там проскакивает: проблема в том, что все учатся по книгам 80-х.

Стоит ли забросить Дэйтела или Прата?

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

Спорно. По факту - почти не пользуются. Только в glibc местами видел, и то эффективности от него там не прибавляется.

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

А кому охота проверять, есть ли реальная оптимизация и польза от нее в случае использования restrict?

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

Теоретически, неплохая задумка. К тому же работает как документация. Но сишники не осиливают.

К тому же Линус, емнип, утверждал что от alias analysis никакого толку.

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

Ну да, люди из комитета ввели это в стандарт, а разработчики компиляторов реализуют эту фичу потому что она никому не нужна, всё логично.

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

Ты разберись в вопросе, чтоб иронизировать. И уж точно не думай, что список полезных фич совпадает с диффом стандартов.

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

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

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

Я иронизирую потому, что как раз изучил (хотя бы поверхностно, по описанию и чужим отзывам) зачем нужен restrict, а от вас никакой конкретики почему это «ненужно» не было, жду.

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

Используют по мере возможностей

Вот самая суть. Хорошо когда используют, переписывать ради переписывания – конечно глупо. Но речь была о том, что некоторые и новый код пишут в стиле k&r, игнорируя хорошие практики.

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

к примеру объявлять переменную как можно ближе к использованию

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

не использовать ++ и — в сложных выражениях

«тире» это что? а «++» и так не видел чтобы в сложных выражениях использовали.

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

«тире» это что?

В разметке 2 минуса слились)

а «++» и так не видел чтобы в сложных выражениях использовали. Может потому и не видели, что в книжках пишут так не делать?) но вообще могут быть и менее очевидные примеры изменения одной переменной в выражении дважды

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

В своём посте под стилем я тоже не скобочки имел в виду, а подходы к написанию кода на С, почерпнутые из книги k&r, после которой был стандарт 89го года и прочие, каждый из которых что-то привносил

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

Чем он теоретически полезен - все изучили. Я говорю о практике. Чего не хватило в моих постах?

1. По наблюдениям, им практически никто и никогда не пользуется. Если есть другие наблюдения - поделись, интересно.

2. Даже там где используется - это зачастую смехотворно. Возьми из C99

fopen(const char * restrict filename, const char * restrict mode)
Можешь объяснить, какой тут толк от restrict?

3. В случае memcpy есть смысл, но практически - только для документации. Если вспомнить что реализация ассемблерная. И оно как правило так: где нужна жесткая микрооптимизация - там пользуют ассемблерные вставки, restrict не при делах.

4. Он сложен. Малая часть сишников вообще в курсе про алиасинг. Без restrict всё работает. С ним, если применить ошибочно, - ломается. Выбор несложен, если не нужна микрооптимизация, но там - см. про ассемблер.

5. В C++ до сих пор нет restrict. Хотя разговоры ведутся, но даже там считают что это сложно (сложнее чем в си, конечно).

В конце концов, я не говорю «ненужно». Я говорю - он не используется.

В то же время designated initializers и variadic macros используются повсеместно, но они в твой список не попали. Значит, список делался без оглядки на реальную полезность.

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

У вас проблема, вы ставите = между используется и полезно, при чём сами пишете, что restrict мало где используется потому что сложно, опасно и без него всё работает. А на счёт того что не вошло в мой список, вы серьёзно думали, что я буду искать по источникам все изменения и сортировать их по «полезности»(не понятно для кого)? Я просто написал первое, что на ум пришло.

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

О VLA надо знать только одно: его не надо использовать. Вообще никогда.

Нет. Можно использовать, но осторожно. А еще можно кастовать указатели в эти VLA. Например, вращение по часовой для произвольного квадрата можно так реализовать

void rotateclockwise(char *ptra, size_t sz)
{
    char (*a_ar)[sz] = (void *)ptra;
    char (*b_ar)[sz]  = malloc(sz*sz);
    if ((void *)b_ar == NULL)
    {
      fprintf(stderr, "ERROR: your two-dimentional array is too big\n");
      exit(EXIT_FAILURE);
    }
    for (size_t y = 0; y < sz; y++)
    {
        for (size_t x = 0; x < sz; x++)
        {
            b_ar[y][x] = a_ar[sz-1-x][y];
        }
    }
    memcpy(a_ar, b_ar, sz*sz);
}
https://wandbox.org/permlink/9gR4Tn8eKs1OUAy2

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

Ну так оно в куче и выделяется через malloc. Тут VLA используется в указателях, для индексации двухмерного массива.

Если же говорить про использование VLA как замены alloca() то это тоже вполне нормальное решение т.к. alloca() не стандартизирован, а VLA - да. И в сравнении с malloc() не требуется лишние выделения памяти на куче, что относительно дорогая операция (только надо не выделять слишком много, чтоб стек не исчерпать).

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

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

Ну так оно в куче и выделяется

VLA в стеке живут, в том-то всё и дело

то так надо и рекурсию запретить

там где С-шка нужна, то есть в микроконтроллерах, стек выжирается рекурсией мгновенно, так оно ещё и весьма дорого, так что да, в С-шке нужно запретить

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

Вот тут в этом фрагменте

    char (*b_ar)[sz]  = malloc(sz*sz);
    if ((void *)b_ar == NULL)
    {
      fprintf(stderr, "ERROR: your two-dimentional array is too big\n");
      exit(EXIT_FAILURE);
    }
память выделяется не в стеке. Но VLA есть.

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

есть-то есть, но толку от него, когда можно просто двойной указатель сделать? более вырвиглазный код написать задача?

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

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

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

Эх, царя на тебя нет!

Давай, вспоминай, в каком случае malloc вернет NULL. А произойдет это лишь в двух случаях: а) ты хочешь памяти больше, чем объем виртуальной, б) ты вылез за пределы лимитов. Ну, а т.к. б) встречается крайне редко, то остается лишь а).

А вот если юзер захочет пару гигов, а ему физически столько выделить ОС не сможет, то malloc все равно что-то вернет. Приколы будут позже, когда юзер попытается эту память использовать.

Итог: всегда выделяй память calloc'ом, а при использовании realloc тут же инициализируй новый кусок памяти.

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

всегда выделяй память calloc'ом, а при использовании realloc тут же инициализируй новый кусок памяти

Тормозно, впустую продувает память.

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

Зато избавишься от ряда проблем.

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

есть-то есть, но толку от него, когда можно просто двойной указатель сделать?

Двойной указатель работает по-другому (не так, как работает указатель на массив известного размера), и не всегда это хорошо. Для двойного указателя у тебя будет массив из указателей на строки. Т.е. для 4x4 это будет:

char **a = malloc(sizeof(char *) * 4);
a[0] = malloc(sizeof(char) * 4);
a[1] = malloc(sizeof(char) * 4);
a[2] = malloc(sizeof(char) * 4);
a[3] = malloc(sizeof(char) * 4);
А это не всегда нужно.

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

так что да, в С-шке нужно запретить

Может лучше TCO стандартизировать, пусть даже и с явной декларацией, чем неявное с кучей ограничений, зависимое от реализации? Да, может быть процессорно-зависимо...

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