LINUX.ORG.RU

Вышел первый том книги А. В. Столярова «Программирование: введение в профессию»

 , ,


24

11

На официальном сайте А. В. Столярова объявлено о выходе первого тома книги «Программирование: введение в профессию». Первый том, озаглавленный «Азы программирования», включает две части: «Введение» и «Язык Паскаль и начала программирования». Обе части, как и вся книга в целом, ориентированы на использование ОС Unix (в основном Linux); в предисловии автор, обращаясь к «коллегам-преподавателям», заявляет, что книга вряд ли будет им полезна, если командная строка ОС Unix не станет их основным инструментом для повседневной работы с компьютером.

Электронная версия первого тома (PDF) доступна на сайте в открытом доступе.

Книга «Программирование: введение в профессию» примечательна тем, что средства на её написание и издание были собраны через краудфандинговую кампанию. По словам автора, это был единственный вариант, позволяющий написать книгу и предоставить открытый доступ к её электронной версии. Приём пожертвований на сайте А. В. Столярова продолжается, поскольку средств для издания последующих томов к настоящему моменту недостаточно.

Как сообщалось ранее в новостной ленте сайта, второй том книги, который выйдет под заголовком «Низкоуровневое программирование», уже практически готов к печати. В него войдут часть о программировании на языке ассемблера NASM для ОС Unix, а также часть, посвящённая языку Си. Пока неясно, войдёт ли в этот же том часть, рассказывающая о принципах построения операционных систем и о возможностях, доступных на уровне системных вызовов ОС Unix, или же эта часть будет оформлена как отдельный том. Сроки издания второго тома также пока неизвестны, поскольку зависят от дальнейшего хода краудфандинговой кампании.

>>> Подробности

★★★

Проверено: anonymous_incognito ()
Последнее исправление: CYB3R (всего исправлений: 5)

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

Вы боитесь слова ``стандарт"?

При чём тут «боюсь»? Я не приемлю стандарты, но это не значит, что я их боюсь. Я вообще много чего не приемлю, а вот чтобы я чего-то всерьёз боялся — не, ну бывает и такое, но редко. И уж точно не слова.

Просто ни у кого, никогда, нигде не может быть достаточно оснований для объявления очередного поделья «стандартом», потому что не может быть оснований диктовать свою волю другим. Следовательно, любая бумажка с надписью «стандарт» — это узурпация полномочий. Ну а узурпаторов я как бы с детства не перевариваю, чего и всем желаю.

Чем наличие определенного диалекта, который стараются поддерживать большинство компиляторов

Это практически идеальная ситуация — при условии, что никто и никогда не заявляет, что этот «определённый диалект», видите ли, «стандарт».

когда все делают что хотят?

Между прочим, именно что все должны делать что хотят. И не делать ничего, чего не хотят. Если при этом образуется некий «определённый диалект», это будет свидетельствовать о том, что достигнут консенсус.

Стандарты же, разумеется, к консенсусам никакого отношения не имеют.

А вы проверяли все свои страшные предположения?

Естественно, а что? Я даже вроде ссылку дал.

Это не проблемы вложенных функций.

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

Мне прям даже интересно стало. А покажете такую программу, которая считает символы (не байты) из stdin?

При чтении из stdin символ и байт — это одно и то же; Unix-way подразумевает, что именно поток байтов есть «всё». Разбор данных в многобайтовых кодировках — вопрос библиотечных реализаций. Впрочем, вы полагаете, что разбор той же utf-8 представляет какие-то трудности? :-) Ну так я её разбирал вручную, трудностей не заметил. Ну, если не считать двоякого представления буквы «ё», но на подобные выверты я считаю прямо-таки своим долгом класть чугунный болт.

С другой стороны, вы что, полагаете, что реализация stdio.h как-то там сложна или волшебна? По мне так там всё просто и понятно, только читать надо не glibc, а тот же musl.

OH SHI~! Какой у вас там компилятор?

4.6.3

А лучше вообще ничего не использовать, ага.

Вообще-то в определённом смысле так оно и есть. Допустимые compile time dependencies — это компилятор и make (обычный make, то есть не cmake), единственная допустимая runtime dependency — ядро. Всё, что используется при сборке, должно быть включено в дерево исходников, всё, что нужно в рантайме — вкомпилировано в бинарник. С точки зрения майнтейнера такая программа идеальна, это zero maintenance. И это правильно, поскольку означает, что разработчик взял на себя решение всех проблем, каких смог, не перекладывая собственные сложности на ни в чём не повинных майнтейнеров.

А виноваты зависимости между библиотеками...

Разумеется. Точнее, виноват стиль мышления, основанный на безусловной допустимости использования библиотек (пришёл, увидел, подключил). Полный отказ от их использования — это противоположная крайность, и, замечу, имеющая отнюдь не столь катастрофические последствия.

А я видел студентов, которые не умеют использовать указатели — значит указатели результат не желания думать?

Если вы внимательно посмотрите на мой тезис и на свой, то, возможно, заметите, что их структура прямо противоположна.

Ничего похожего. Текст — это текст. Или мы сейчас бинарниками общаемся? Вы робат?

Минуточку, так по-вашему .doc, выплюнутый мелкомягким вордом — это текст? PDF — это текст? DJVU — это текст? Э-ммм (вкрадчивым голосом, ожидая подхода санитаров) ну да, конечно, текст, разумеется, текст, и JPEG — текст, вдруг там кто-то доску объявлений сфоткал, и MP3 — текст, там ведь может быть песня, а у песен тоже есть слова... вообще кругом один текст... вяжите его, ребята...

И все это мракобесие — только для того, что бы возвращать указатель на грубо говоря замыкание. Для вызова внутренней функции из внешней всё это не нужно.

Ничего подобного. «Грубо говоря замыкания» вообще не поддерживаются статическими языками, включая Паскаль (несмотря на то, что исходное виртовское описание Паскаля вроде бы как раз это допускало), поскольку для них пришлось бы весь стековый фрейм куда-то за угол закапывать, и тут никакие трамплины уже не помогли бы. Enter с двумя параметрами нужна для организации вложенных стековых фреймов с указателями на начало внешнего (объемлющего) фрейма, или, если точнее, с указателями на ВСЕ объемлющие фреймы, поскольку вложенность-то может быть больше одного уровня. Трамплины приходится применять, когда внутренняя функция вызывается по указателю _до_ того, как выполнение объемлющей функции завершилось (то есть никаких замыканий, естественно). Собственно, при взятии адреса вложенной функции как раз указатель на трамплин и формируется. В момент возврата из объемлющей функции её стековый фрейм исчезает вместе со всеми трамплинами, которые в нём успели нагвоздить.

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

вяжите его, ребята

Тебе намекают, что общаетесь вы кириллицей, а кириллицы в ASCII нет.

«Грубо говоря замыкания» вообще не поддерживаются статическими языками

А как же лямбды в C++11? Они что, тоже с трамплинами?

i-rinat ★★★★★
()
Ответ на: комментарий от Croco

Просто ни у кого, никогда, нигде не может быть достаточно оснований для объявления очередного поделья «стандартом», потому что не может быть оснований диктовать свою волю другим. Следовательно, любая бумажка с надписью «стандарт» — это узурпация полномочий. Ну а узурпаторов я как бы с детства не перевариваю, чего и всем желаю.

Вас кто то заставляет использовать ANSI или ISO C?

Это практически идеальная ситуация — при условии, что никто и никогда не заявляет, что этот «определённый диалект», видите ли, «стандарт».

Почему вы решаете, кому и как называть этот диалект?

Естественно, а что? Я даже вроде ссылку дал.

Так вот, в простых случаях никакого оверхеда от вложенных функции нет.

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

Возможность писать функции длиннее 25 строк влияет на мышление именно так, как вы говорите. Срочно запрещаем функции длиннее 25 строк.

При чтении из stdin символ и байт — это одно и то же; Unix-way подразумевает, что именно поток байтов есть «всё». Разбор данных в многобайтовых кодировках — вопрос библиотечных реализаций.

Это вам так отцы-основатели сказали?

Впрочем, вы полагаете, что разбор той же utf-8 представляет какие-то трудности? :-) Ну так я её разбирал вручную, трудностей не заметил. Ну, если не считать двоякого представления буквы «ё», но на подобные выверты я считаю прямо-таки своим долгом класть чугунный болт.

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

4.6.3

И что, он не умеет в stdbool.h? Или сотни мейнтейнеров, оказавшиеся вами одним, даже не проверяли?

Вообще-то в определённом смысле так оно и есть. Допустимые compile time dependencies — это компилятор и make (обычный make, то есть не cmake), единственная допустимая runtime dependency — ядро. Всё, что используется при сборке, должно быть включено в дерево исходников, всё, что нужно в рантайме — вкомпилировано в бинарник. С точки зрения майнтейнера такая программа идеальна, это zero maintenance. И это правильно, поскольку означает, что разработчик взял на себя решение всех проблем, каких смог, не перекладывая собственные сложности на ни в чём не повинных майнтейнеров.

То есть каждый разработчик каждой KDE-шной проги должен пилить свое KDE?

Если вы внимательно посмотрите на мой тезис и на свой, то, возможно, заметите, что их структура прямо противоположна.

Вы утверждаете, что вред от VLA только у обезьян и студентов. От указателей у этих категорий вреда еще больше.

Минуточку

На вопросы ответьте.

Трамплины приходится применять, когда внутренняя функция вызывается по указателю _до_ того, как выполнение объемлющей функции завершилось (то есть никаких замыканий, естественно).

Что?

int simplep(int pa) {
    int n(int na) {
        return na+1;
    }
    int (*fp)(int) = n;
    return fp(pa);
}
        .text
        .globl  simplep
        .type   simplep, @function
simplep:
.LFB0:
        .cfi_startproc
        leal    1(%rdi), %eax   #, D.1762
        ret
        .cfi_endproc
.LFE0:
        .size   simplep, .-simplep
        .ident  "GCC: (Gentoo 4.9.3 p1.3, pie-0.6.3) 4.9.3"
        .section        .note.GNU-stack,"",@progbits

Что это тогда?

#include <stdio.h>

typedef int (*funp)(int);

funp get_cl(int a) {
    int cl(int b) {
        return a + b;
    }
    return cl;
}

int main() {
    funp fp = get_cl(10);
    printf("%d\n", fp(5));
    return 0;
}
        .text
        .type   cl.2408, @function
cl.2408:
.LFB25:
        .cfi_startproc
        movl    %edi, %eax      # b, D.2444
        addl    (%r10), %eax    # CHAIN.1_2(D)->a, D.2444
        ret
        .cfi_endproc
.LFE25:
        .size   cl.2408, .-cl.2408
        .globl  get_cl
        .type   get_cl, @function
get_cl:
.LFB24:
        .cfi_startproc
        subq    $56, %rsp       #,
        .cfi_def_cfa_offset 64
        movq    %fs:40, %rax    #, tmp94
        movq    %rax, 40(%rsp)  # tmp94, D.2448
        xorl    %eax, %eax      # tmp94
        movl    %edi, (%rsp)    # a, FRAME.0.a
        leaq    4(%rsp), %rax   #, tmp88
        movw    $-17599, 4(%rsp)        #, FRAME.0.cl
        movl    $cl.2408, %edx  #, tmp90
        movl    %edx, 2(%rax)   # tmp90, FRAME.0.cl
        movw    $-17847, 6(%rax)        #, FRAME.0.cl
        movq    %rsp, 8(%rax)   #, FRAME.0.cl
        movl    $-1864106167, 16(%rax)  #, FRAME.0.cl
        movq    40(%rsp), %rcx  # D.2448, tmp95
        xorq    %fs:40, %rcx    #, tmp95
        je      .L3     #,
        call    __stack_chk_fail        #
.L3:
        addq    $56, %rsp       #,
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE24:
        .size   get_cl, .-get_cl
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "%d\n"
        .text
        .globl  main
        .type   main, @function
main:
.LFB26:
        .cfi_startproc
        subq    $8, %rsp        #,
        .cfi_def_cfa_offset 16
        movl    $10, %edi       #,
        call    get_cl  #
        movl    $5, %edi        #,
        call    *%rax   # fp
        movl    %eax, %edx      # D.2452,
        movl    $.LC0, %esi     #,
        movl    $1, %edi        #,
        movl    $0, %eax        #,
        call    __printf_chk    #
        movl    $0, %eax        #,
        addq    $8, %rsp        #,
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE26:
        .size   main, .-main

deadskif
()
Ответ на: комментарий от i-rinat

Тебе намекают, что общаетесь вы кириллицей, а кириллицы в ASCII нет.

Ну и? Совершенно верно, тут на сайте UTF-8, и она, строго говоря, никакой не текст, хотя в некоторых случаях её и рассматривают в качестве такового.

А как же лямбды в C++11? Они что, тоже с трамплинами?

А они не функции. Вот то есть вообще от слова «совсем». Иначе бы не требовались, например, пляски с std::function.

Но вообще тратить своё время на обсуждение C++11 и более поздних вариаций я не собираюсь, скажу сразу. Этот бастард того не стоит.

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

Вас кто то заставляет использовать ANSI или ISO C?

Вообще-то нет, поскольку любой технический стандарт имеет сугубо рекомендательный статус. Только не все это знают. И вот этим «всем» постоянно приходится объяснять, что они неправы. Например, отвечать на вопрос, ну почему же нельзя использовать те же VLA, когда они есть в стандарте и всеми компиляторами поддерживаются. Время на это тратить. А жизнь вообще-то коротка.

Почему вы решаете, кому и как называть этот диалект?

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

Замечу, от стандартизаторов вреда изрядно больше, чем от любителей кирпичами швыряться.

Это вам так отцы-основатели сказали?

Это я так сказал. Кто не согласен — идёт на... э... в общем, туда.

Вы программу то приведите.

какую, для подсчёта UTF-ных символов на stdin'е?

    static unsigned char buf[4096];
    int rc, i;
    int count = 0;
    while((rc = sys_read(1, buf, sizeof(buf))) > 0)
        for(i = 0; i < rc; i++)
            if((buf[i] & 0xc0) != 0x80) count++;

сложно, аж жуть

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

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

И что, он не умеет в stdbool.h?

Данный конкретный — не умеет, проверено. Возможно, в Owl'е усечённый вариант, я не вникал.

сотни мейнтейнеров, оказавшиеся вами одним

Вы хотя бы приблизительно представляете, сколько сейчас в эксплуатации машин с системами, у которых двадцать лет как настал EndOfLife? Со всякими допотопными AIX'ами (именно допотопными, не современными), HPUX'ами, Solaris'ами и прочими? У меня приятель один на жизнь зарабатывает тем, что оживляет медицинскую технику типа всяких томографов, к которой прилагается управляющий комп — и оный комп, разумеется, сдыхает первым (чаще всего тупо диски осыпаются), а «фирменное» обслуживание, подразумевающее замену компа, стоит как две трети этого томографа (и это не чуть-чуть). Вот там компиляторы Це встречаются не то что без stdbool, они даже строковые литералы склеивать не умеют, ибо pre-ANSI epoch. И это только один частный кейс. Компьютерный утиль, который во что бы то ни стало необходимо поддерживать в работающем состоянии, встречается отнюдь не только в медицине.

Да и не ограничивается это всё утилем, если подумать.

То есть каждый разработчик каждой KDE-шной проги должен пилить свое KDE?

Каждый разработчик каждой KDE-шной проги должен добровольно прыгнуть в биореактор вместе с разработчиками самого KDE. И да, гнома это тоже касается.

Вы утверждаете, что вред от VLA только у обезьян и студентов. От указателей у этих категорий вреда еще больше.

Я утверждаю, что от VLA вред всем поголовно, это во-первых. Во-вторых, обезьяны и студенты, которые не понимают, что делают, указатели применять не могут — потому что попытки их применения без понимания происходящего приводят к немедленному коредампу и истерике виде «я написал, а оно не работает». Тогда как применение VLA индивидом, не понимающим, что творит, очень даже проходит.

На вопросы ответьте.

Вообще-то я уже ответил, но для отдельных категорий повторяю: совершенно верно, текст, представленный в UTF-8 (здесь на сайте именно она), текстом не является. Можно сформулировать иначе: да, кодировка UTF-8 представляет собой бинарный формат, как и любая юникодная кодировка. В отличие от других юникодных кодировок, UTF-8 проявляет _некоторые_ свойства, характерные для текста, но это не делает её текстом.

Что?

То. Разумеется, в вашем примере «вложенная» функция никак не использует контекст, то есть ей не нужен доступ к объемлющему фрейму, а компилятор всё-таки не полные идиоты писали. Вы попробуйте из вложенной функции локальные переменные объемлющей функции подёргать, вот где веселуха начнётся.

Что это тогда?

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

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

Чёрт, дескриптор таки перепутал, следует читать sys_read(0, далее по тексту.

Как говорят, и про старуху бывает порнуха.

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

Ну и?

Ты написал: «ASCII-текст — это текст, а всё остальное — это бинарник». Из чего легко можно вывести, что русский текст — это не текст, а бинарник, так как в ASCII нет кирилицы. (Не говоря уже CJK). Тут явное противоречие, стало быть изначальное утверждение было неверным.

тут на сайте UTF-8, и она, строго говоря, никакой не текст

Верно, это способ кодирования текста в биты. У меня складывается ощущение, что ты путаешь текст и кодировки.

А они не функции.

пляски с std::function.

Это не важно, их можно использовать, этого достаточно. А с std::function ещё и размер фиксированный. Так что поддерживаются, без трамплинов. Тот факт, что у тебя своё определение «статических языков», мало что меняет.

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

Словесные спекуляции, основанные на омонимичности некоторых терминов, суть занятие довольно тухлое. Во всяком случае, лично мне не интересное.

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

sys_read

Ты этому студентов учишь? И так у почти что каждого программиста есть синдром «смотри, как я могу». Если выпендриваться, через пару месяцев будешь долго вникать, как работает написанный тобой же код, доказывать, что он работает правильно. И так каждый раз, когда такое место всплывёт во время отладки. Чудесно.

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

Это действительно тот пример, на который нужно ориентироваться? Может, тогда в ВУЗах учить всякому десятилетия назад устаревшему хламу? А что, сколько ещё кода на каком-нибудь COBOL'е, Fortran 66 или MUMPS? Без работы не останутся. Эти системы ещё нас переживут.

i-rinat ★★★★★
()
Ответ на: комментарий от Croco

омонимичности

В том-то и дело, что не было там омонимов.

Но не ты первый, не ты последний. Даже тут на форуме был персонаж, известный своей ненавистью к UTF-8 и юникоду вообще.

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

Ты этому студентов учишь?

В том числе и этому. Едва ли не единственное достоинство plain C состоит в том, что этот язык допускает Zero Runtime и, соответственно, отстригание стандартной библиотеки ко всем чертям и ихним бабушкам. Я тут несколько лет подряд читаю спецкурс «Низкоуровневое программирование», в котором в том числе (хотя отнюдь не только) показываю, как на plain C сделать программу без стандартной библиотеки — то есть написав на асме окрестности метки _start и обёртки для сисколлов. Дело, конечно, не в том, что на Це только так и нужно писать (я сам так не пишу), дело в том, что на Це так ВОЗМОЖНО писать. А больше, замечу, так писать больше ни на чём нельзя, в смысле невозможно. И лишь по той причине, что на Це так писать можно, а больше ни на чём, Це и занимает то положение, которое занимает. И этому, таки да, я студентов учил, учу и учить буду.

Это действительно тот пример, на который нужно ориентироваться?

Исходный тезис был такой: stdbool.h не даёт ничего (вот то есть вообще ничего, никакого профита), зато есть люди, которым его применение приносит геморрой. Контр-тезис оппонента сводился к тому, что таких людей не существует. Я их предъявил.

«Ориентироваться» не предлагал и не предлагаю, принять их существование во внимание — считаю целесообразным, особенно когда речь идёт о заведомо бесполезной чуши вроде stdbool.

Croco ★★★
() автор топика
Ответ на: комментарий от i-rinat

В том-то и дело, что не было там омонимов.

Ещё как было. Там слово «текст» использовано в совершенно разных смыслах, взятых из разных предметных областей.

Даже тут на форуме был персонаж, известный своей ненавистью к UTF-8 и юникоду вообще.

Прям как в том анекдоте: как, ОДИН персонаж? Да их тут тыщи!

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

Вообще-то нет, поскольку любой технический стандарт имеет сугубо рекомендательный статус. Только не все это знают. И вот этим «всем» постоянно приходится объяснять, что они неправы. Например, отвечать на вопрос, ну почему же нельзя использовать те же VLA, когда они есть в стандарте и всеми компиляторами поддерживаются. Время на это тратить. А жизнь вообще-то коротка.

Пфф.. В интернете кто-то не прав и им нужно объяснять, что VLA нельзя использовать, потому что студенты в него не могут(а точнее потому, что он вам не нравится)?

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

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

Уйдите со стройки, там люди делом заняты. Это не их проблема, что вам их каска не нравится.

Это я так сказал. Кто не согласен — идёт на... э... в общем, туда.

Бгг. Чет все разработчики юниксов к вам не прислушиваются.

сложно, аж жуть

Не компиляется. Как странно.

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

Может и ядро сразу свое использовать?

Данный конкретный — не умеет, проверено. Возможно, в Owl'е усечённый вариант, я не вникал.

Ну значит кто то очень криворук.

Вы хотя бы приблизительно представляете, сколько сейчас в эксплуатации машин с системами, у которых двадцать лет как настал EndOfLife? Со всякими допотопными AIX'ами (именно допотопными, не современными), HPUX'ами, Solaris'ами и прочими? У меня приятель один на жизнь зарабатывает тем, что оживляет медицинскую технику типа всяких томографов, к которой прилагается управляющий комп — и оный комп, разумеется, сдыхает первым (чаще всего тупо диски осыпаются), а «фирменное» обслуживание, подразумевающее замену компа, стоит как две трети этого томографа (и это не чуть-чуть). Вот там компиляторы Це встречаются не то что без stdbool, они даже строковые литералы склеивать не умеют, ибо pre-ANSI epoch. И это только один частный кейс. Компьютерный утиль, который во что бы то ни стало необходимо поддерживать в работающем состоянии, встречается отнюдь не только в медицине.

И что, туда собирают современный bash, а он из-за stdbool не собирается?

Польза от stdint, stdalign, stddef напрочь перебивают то, что у кого то может не быть stdbool.

Я утверждаю, что от VLA вред всем поголовно, это во-первых. Во-вторых, обезьяны и студенты, которые не понимают, что делают, указатели применять не могут — потому что попытки их применения без понимания происходящего приводят к немедленному коредампу и истерике виде «я написал, а оно не работает». Тогда как применение VLA индивидом, не понимающим, что творит, очень даже проходит.

А вот и нифига. Не полное понимание указателей может выстрелить хрен знает когда.

Каждый разработчик каждой KDE-шной проги должен добровольно прыгнуть в биореактор вместе с разработчиками самого KDE. И да, гнома это тоже касается.

А так же любой Х-овой и вообще любой, использующей библиотеки. Отлично, что тут скажешь.

Вообще-то я уже ответил, но для отдельных категорий повторяю: совершенно верно, текст, представленный в UTF-8 (здесь на сайте именно она), текстом не является. Можно сформулировать иначе: да, кодировка UTF-8 представляет собой бинарный формат, как и любая юникодная кодировка. В отличие от других юникодных кодировок, UTF-8 проявляет _некоторые_ свойства, характерные для текста, но это не делает её текстом.

То есть вы со мной бинарниками все-таки общаетесь. Ну вообще шикарно.

То. Разумеется, в вашем примере «вложенная» функция никак не использует контекст, то есть ей не нужен доступ к объемлющему фрейму, а компилятор всё-таки не полные идиоты писали. Вы попробуйте из вложенной функции локальные переменные объемлющей функции подёргать, вот где веселуха начнётся.

Пфф.

int sum(int a, int b) {
    static int sc = 0;
    int c = a + b;
    int sumb(int na) {
        return na + b + c + sc;
    }
    sc++;
    return sumb(a);
}
        .text
        .globl  sum
        .type   sum, @function
sum:
.LFB0:
        .cfi_startproc
        addl    %esi, %edi      # b, D.1783
        movl    sc.1746(%rip), %eax     # sc, tmp94
        addl    $1, %eax        #, D.1783
        movl    %eax, sc.1746(%rip)     # D.1783, sc
        leal    (%rax,%rdi,2), %eax     #, D.1783
        ret
        .cfi_endproc
.LFE0:
        .size   sum, .-sum
        .local  sc.1746
        .comm   sc.1746,4,4

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

Это проблемы макак. В си они могут из чего угодно запутанного кода породить. Это не проблема вложенных функций и С.

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

Пфф

Ага, и где call? Где call, я таки вас спрашиваю? Компилятор эту однострочную функцию заинлайнил благополучно, то есть превратил фактически в макрос — конечно, в таком раскладе можно и без трамплина обойтись. Но не всякую функцию можно инлайнить.

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

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

Ага, и где call? Где call, я таки вас спрашиваю? Компилятор эту однострочную функцию заинлайнил благополучно, то есть превратил фактически в макрос — конечно, в таком раскладе можно и без трамплина обойтись. Но не всякую функцию можно инлайнить.

facepalm. Про -fno-inline не в курсе, что-ли?

i-rinat ★★★★★
()
Ответ на: комментарий от Croco

И что, он не умеет в stdbool.h?

Данный конкретный — не умеет, проверено. Возможно, в Owl'е усечённый вариант, я не вникал.

GCC в текущием стабильном выпуске Openwall Linux нормально поддерживает stdbool.h.

i-rinat ★★★★★
()
Ответ на: комментарий от Croco

Ага, и где call? Где call, я таки вас спрашиваю?

А он обязательно должен быть?

Но не всякую функцию можно инлайнить.

Примеры не инлайнящихся вложенных функций можно?

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

``Стандарты это плохо, потому что я так сказал" и некомпилирующийся код — это конечно очень технические фразы.

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

А он обязательно должен быть?

Ежели хотите трамплинами полюбоваться, то должен быть не только call, но и взятие адреса функции, и её передача параметром. А если хотите полюбоваться только на формирование многоуровневого стекового фрейма — достаточно, чтобы был call и обращение к локальным переменным объемлющего фрейма.

Примеры не инлайнящихся вложенных функций можно?

Ай-вей, да пожалуйста:

void sumprod(int *vec, int n, int *sum, int *prod)
{
    int plus(int a, int b) { return a + b; }
    int times(int a, int b) { return a * b; }
    int reduce(int *vec, int len, int start, int (*op)(int, int))
    {
        return !len ? start : (*op)(*vec, reduce(vec+1, start, len-1, op));
    }
    *sum = reduce(vec, n, 0, &plus);
    *sum = reduce(vec, n, 1, &times);
}

Вот тут во всю морду :-) Асмовый листинг не привожу, кому надо — тот gcc -S сам сделает. А то он зело большой получился:

crocodil@frock:~/work/misc$ wc -l nested.s 
588 nested.s
crocodil@frock:~/work/misc$ 

``Стандарты это плохо, потому что я так сказал"

Вообще-то я сказал совершенно не это: стандарты — это плохо, потому что их создание есть узурпация полномочий и необоснованное навязывание всему миру своего видения проблемы.

и некомпилирующийся код

crocodil@frock:~/work/misc$ cat utf8cnt.c 
int sys_read(int fd, void *buf, int buflen);

int utf8cnt()
{
    static unsigned char buf[4096];
    int rc, i;
    int count = 0;
    while((rc = sys_read(0, buf, sizeof(buf))) > 0)
        for(i = 0; i < rc; i++)
            if((buf[i] & 0xc0) != 0x80) count++;
    return count;
}
crocodil@frock:~/work/misc$ gcc -Wall -g -c utf8cnt.c 
crocodil@frock:~/work/misc$

Ни единого ворнинга. ЧЯДНТ?

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

Ежели хотите трамплинами полюбоваться, то должен быть не только call, но и взятие адреса функции, и её передача параметром. А если хотите полюбоваться только на формирование многоуровневого стекового фрейма — достаточно, чтобы был call и обращение к локальным переменным объемлющего фрейма.

Я не хочу, мне просто интересно, вы то знаете, когда генерируются трамплины.

Ай-вей, да пожалуйста

Окей, не инлайнится, но трамплин не генерируется.

А то он зело большой получился

У меня не такой уж и большой

        .text
        .type   plus.1750, @function
plus.1750:
.LFB1:
        .cfi_startproc
        leal    (%rdi,%rsi), %eax       #, D.1790
        ret
        .cfi_endproc
.LFE1:
        .size   plus.1750, .-plus.1750
        .type   times.1754, @function
times.1754:
.LFB2:
        .cfi_startproc
        movl    %edi, %eax      # a, D.1792
        imull   %esi, %eax      # b, D.1792
        ret
        .cfi_endproc
.LFE2:
        .size   times.1754, .-times.1754
        .type   reduce.1762, @function
reduce.1762:
.LFB3:
        .cfi_startproc
        movl    %edx, %eax      # start, D.1794
        testl   %esi, %esi      # len
        je      .L8     #,
        pushq   %rbp    #
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        pushq   %rbx    #
        .cfi_def_cfa_offset 24
        .cfi_offset 3, -24
        subq    $8, %rsp        #,
        .cfi_def_cfa_offset 32
        movq    %rcx, %rbx      # op, op
        movl    %edx, %r8d      # start, start
        movq    %rdi, %rbp      # vec, vec
        leal    -1(%rsi), %edx  #, D.1794
        leaq    4(%rdi), %rdi   #, D.1795
        movl    %r8d, %esi      # start,
        call    reduce.1762     #
        movl    %eax, %esi      # D.1794,
        movl    0(%rbp), %edi   # *vec_5(D),
        call    *%rbx   # op
        addq    $8, %rsp        #,
        .cfi_def_cfa_offset 24
        popq    %rbx    #
        .cfi_restore 3
        .cfi_def_cfa_offset 16
        popq    %rbp    #
        .cfi_restore 6
        .cfi_def_cfa_offset 8
.L8:
        rep ret
        .cfi_endproc
.LFE3:
        .size   reduce.1762, .-reduce.1762
        .globl  sumprod
        .type   sumprod, @function
sumprod:
.LFB0:
        .cfi_startproc
        pushq   %r12    #
        .cfi_def_cfa_offset 16
        .cfi_offset 12, -16
        pushq   %rbp    #
        .cfi_def_cfa_offset 24
        .cfi_offset 6, -24
        pushq   %rbx    #
        .cfi_def_cfa_offset 32
        .cfi_offset 3, -32
        movq    %rdi, %rbp      # vec, vec
        movl    %esi, %r12d     # n, n
        movq    %rdx, %rbx      # sum, sum
        movl    $plus.1750, %ecx        #,
        movl    $0, %edx        #,
        call    reduce.1762     #
        movl    %eax, (%rbx)    # D.1797, *sum_6(D)
        movl    $times.1754, %ecx       #,
        movl    $1, %edx        #,
        movl    %r12d, %esi     # n,
        movq    %rbp, %rdi      # vec,
        call    reduce.1762     #
        movl    %eax, (%rbx)    # D.1797, *sum_6(D)
        popq    %rbx    #
        .cfi_def_cfa_offset 24
        popq    %rbp    #
        .cfi_def_cfa_offset 16
        popq    %r12    #
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE0:
        .size   sumprod, .-sumprod

Вообще-то я сказал совершенно не это: стандарты — это плохо, потому что их создание есть узурпация полномочий и необоснованное навязывание всему миру своего видения проблемы.

Это вам чудится, что вам кто то что то навязывает.

программу
Ни единого ворнинга. ЧЯДНТ?

Программу не приводите.

Заодно будет интересно посмотреть на программу же, но без libc(на чем вы так настаиваете), раз уж для этого почти все есть.

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

Окей, не инлайнится, но трамплин не генерируется.

Потому что нет обращений к локальным переменным объемлющей функции. Вы же хотели «пример неинлайнящихся».

Ну вот вам модификация, наслаждайтесь (пока писал, чуть не стошнило от собственного кода).

void sumprod(int *vec, int n, int *sum, int *prod)
{
    int accum;
    int plus(int a) { return accum + a; }
    int times(int a) { return accum * a; }
    void reduce(int *vec, int len, int (*op)(int))
    {
        if(!len) return;
        accum = op(*vec);
        reduce(vec+1, len-1, op);
    }
    accum = 0; reduce(vec, n, &plus); *sum = accum;
    accum = 1; reduce(vec, n, &times); *prod = accum;
}

У меня не такой уж и большой

У вас 64 бита, ну да, чуток покороче. Хотя для такой дебильной цели всё равно слишком большой. И разобраться нереально.

Программу не приводите.

мЯнуточку, вы утверждали, что код не компилируется. Для успешной компиляции программа целиком не нужна.

Заодно будет интересно посмотреть на программу же, но без libc(на чем вы так настаиваете), раз уж для этого почти все есть.

Этот модуль libc не использует, под sys_read я имел в виду ассемблерную обёртку, которая обращается к ядру. Чтобы добить эту программу целиком, нужно числа в текст переводить, не бог весть как сложно, но прямо сейчас у меня времени нет — вечером паровоз, а я ещё собираться не начинал. Второй том моего опуса вчера ушёл в печать, там пример без libc (с написанными на nasm'е обёртками сисколлов и точкой входа, которая _start) подробно разобран. Вернусь 24.06, примерно тогда, если всё будет в порядке, книжка будет уже готова и я электронный вариант, как всегда, выложу.

Это вам чудится, что вам кто то что то навязывает.

Заблуждаетесь. Даже наша с вами дискуссия — наглядный пример обратного. Для большинства людей слово «стандарт» — повод действовать, причём действовать некритически (ведь «это же стандарт»). Люди, разборчивые в выборе инструментов и не теряющие способности критически мыслить, составляют меньшинство и во многих случаях вынуждены прогибаться под оголтелую толпу. Если бы не было слова «стандарт», не было бы и оголтелой толпы — вместо этого каждая группа людей, сохраняющих критическое мышление, собирала бы вокруг себя свой круг использующих ту или иную спецификацию, по количеству примерно соответствующий качеству спецификации. Заметим, даже мартышки при этом были бы вынуждены сравнивать спецификации между собой, так что количество думающих было бы существенно больше. А так — стандарт, чо.

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

Ну вот вам модификация, наслаждайтесь (пока писал, чуть не стошнило от собственного кода).

Окей, теперь трамплины генерятся. Именно так делать не надо.

У вас 64 бита, ну да, чуток покороче. Хотя для такой дебильной цели всё равно слишком большой. И разобраться нереально.

Если вынести функции, будет сильно короче и понятнее?

мЯнуточку, вы утверждали, что код не компилируется. Для успешной компиляции программа целиком не нужна.

Я просил программу, а не кусок кода.

Чтобы добить эту программу целиком, нужно числа в текст переводить, не бог весть как сложно, но прямо сейчас у меня времени нет

Вывод числа сложнее, чем простыня поста? Отлично.

с написанными на nasm'е обёртками сисколлов и точкой входа, которая _start

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

Заблуждаетесь. Даже наша с вами дискуссия — наглядный пример обратного. Для большинства людей слово «стандарт» — повод действовать, причём действовать некритически (ведь «это же стандарт»). Люди, разборчивые в выборе инструментов и не теряющие способности критически мыслить, составляют меньшинство и во многих случаях вынуждены прогибаться под оголтелую толпу. Если бы не было слова «стандарт», не было бы и оголтелой толпы — вместо этого каждая группа людей, сохраняющих критическое мышление, собирала бы вокруг себя свой круг использующих ту или иную спецификацию, по количеству примерно соответствующий качеству спецификации. Заметим, даже мартышки при этом были бы вынуждены сравнивать спецификации между собой, так что количество думающих было бы существенно больше. А так — стандарт, чо.

А кто мешает делать сейчас так? Определяете в _своем_ проекте кодстайл и вуаля. Bell Labs пошли дальше и запили свой диалект для plan9. Немного другой препроцессор, другая стандартная библиотека. А в мейнстриме, в общем то, так и есть, как вы описали. Просто у почти всех компиляторов есть некое подмножество, на котором можно писать. Для простоты это подмножество тянут к стандарту. А мартышки будут говнокодить хоть на K&R, хоть на C11.

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