LINUX.ORG.RU

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

 , ,


24

11

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

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

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

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

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

★★★

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

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

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

Поэтому ожидаю страниц 6 вялотекущего обсуждения.

Маловато будет!

Вангую страниц 15 :-)

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

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

Всего 6? Разве оскудел ЛОР царями?

crutch_master ★★★★★
()
Ответ на: Не впечатлило от Twissel

Может немного не в тему, но как представленная в курсе ВМ, мне поможет понять, к примеру, как устроен p-code Visual Basic 6?

Мсье знает толк.

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

Ну может совсем немножечко передернул, ладно уже ;-)

Twissel ★★★★★
()

в следующую редакцию наряду с «Вильгельмом Шиккардом» эрудично и пользительно назвать Антикитерный механизм как пример инструмента.

qulinxao ★★☆
()

пред историю Юникса стоит начать с публикации Томсона в асм статьи за который он затем патент отхватил вот за эту Ken Thompson, “Regular expression search algorithm,” Communications of the ACM 11(6) (June 1968) http://www.fing.edu.uy/inco/cursos/intropln/material/p419-thompson.pdf

это существенно ибо юниксы писались в ed с интенсивным использование регулярок при редактировании (фактически вместо шелла сидели в ed и обращались к шеллу через ! ) -

если для не программистов может интересно про мультикс и компьютерные игры для прогеров интересно знать роль регулярок в генезисе Юникса и Си (возможно многие синтнаксические нюансы исходного Си тем его отличают от обычных языков программирования Алгол семейства(начиная с Паскаля того же)) так это его большее удобство к редактированию Си через регулярки ed

qulinxao ★★☆
()

По видимому, причина в том что Unix оказался первой операционной системой, переписанной на языке высокого уровня, а Си стал этим языком.

Unix явно не первая ОС написанная на hlpl тот же ранее упомянутый мультикс писался на pl/i cpl

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

А разве $DIALOG относится к стандартным переменным окружения?

Вообще-то $DIALOG, это переменная в скрипте. А почему переменная, потому что в разных дистрибутивах dialog имеет несколько инкарнаций. Используется и в манах по этой утилите, и в рабочих скриптах.

#!/bin/bash
DIALOG=${DIALOG=dialog}

А вообще само весёлое, это писать на TCL/TK, хуже чем на perl получается....

Хм... причем тут TCL/TK?

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

Используется и в манах по этой утилите, и в рабочих скриптах.

Специально перечитал man на dialog, нет там упоминания про переменную окружения DIALOG. Я просто придираюсь, если вставляете в пример какую-то нестандартную отсебятину, её надо явно определять выше:

DIALOG=${DIALOG=dialog}
...
$DIALOG --title «Ввод данных» --clear \
 --inputbox «Привет! Перед вами пример ввода даных\nВведите своё имя:» 16 51 2> $tempfile

Хм... причем тут TCL/TK?

Да просто вспомнился такой-же мозгодробящий синтаксис:

pack [entry .e -textvar e -width 50]
bind .e <Return> {catch {expr [string map {/ *1.0/} $e]} res; append e " = $res"} ;# RS% 
ASM ★★
()
Ответ на: комментарий от ASM

Я просто придираюсь, если вставляете в пример какую-то нестандартную отсебятину, её надо явно определять выше

Согласен, в первое сообщение вставил чисто кусок, иллюстрирующий мой текст.

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

Сам преподаю Си на втором курсе студентам, которые уже знают Паскаль

И.Волкова со своим научруком с АЯ уже не преподают? По-прежнему там Си с классами? Каким компилятором учите пользоваться? (у нас был BC++ 3.1 и C/IBM RT).

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

Розничные 1100 рублей - как-то дорого.

При тираже в 300 экземпляров это я ещё дёшево отделался. Эффект малосерийного производства.

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

И.Волкова со своим научруком с АЯ уже не преподают?

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

Компилятор сейчас на втором курсе только один — gcc :-) В третьем семестре plain C, в четвёртом C++. А вот откуда вы взяли «Си с классами», я не знаю, C++ в программу вводили уже при мне, в 2001 году, если не ошибаюсь.

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

Ну STL ладно, а в C99/C11 то что плохого? Я так понимаю все прочие плюшки C++03/C++11 тоже плохо(: ?

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

а в C99/C11 то что плохого?

Абсолютно всё, начиная с VLA, типа _Complex и L-строковых констант, заканчивая самим фактом, что кто-то сваял очередную бумажку, на которой написано, что она, видите ли, «стандарт».

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

VLA, типа _Complex и L-строковых констант

А что в них плохого то(: ?

кто-то сваял очередную бумажку, на которой написано, что она, видите ли, «стандарт».

А как вы предлагаете писать софт и компиляторы, что бы софт разными компиляторами компилялся вообще и правильно в частности? Никаких отступлений от K&R C?

int foo(a, p) 
    int a; 
    char *p; 
{ 
    return 0; 
}

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

А вот откуда вы взяли «Си с классами», я не знаю, C++ в программу вводили уже при мне, в 2001 году, если не ошибаюсь.

И.Волкова вела у нас семинар в 1996-1997 году, по-сути рассказывалось про Си с классами, никаких iostream.

pacify ★★★★★
()

как аргумент в обращении «кул хацкеров знающих что С круть и а паскакаль суксь» на путь истиног(х)а программирования при начале обучения Паскаля(и педагогически и политически верный шаг ибо Паскаль до сих пор лингва франка в старшей школе по СНГ там где реально программированию ...) есть книжка от К из КиР

Керниган Плоджер Инструментальные средства программирования на языке Паскаль.

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

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

Но в вашем контексте, пожалуй, соглашусь.

arcanis ★★★★
()

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

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

«Язык Си и начальное обучение программированию»

Нет, это учебник по началам программирования. НАЧАЛАМ. Не «Программирование на языке Паскаль» или «Программирование на ассемблере имярек», а именно «Начала программирования». Без привязки к «промышенному языку».

Одно то, что в учебнике есть внятно объясненные указатели и совевременные отсылки к «поймите/вспомните/перечитайте, как это всё в железе работает», делает существование учебника вельми нужным.

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

Подтверждаю. Хоть сам пользуюсь x86, но после того как покопался в системе команд - возненавидел. Реально кг/ам. Такое впечатление, что объединили в одну систему команд несколько разных, связав кучей костылей.

KUser
()

When Dennis Ritchie got the first C compiler going on PDP-11 UNIX, descriptors the language naturally inherited the simple I/O model of its host operating

system.

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

Никаких отступлений от K&R C?

Ну почему же, спецификация, известная как K&R — не единственная существующая спецификация Си. Лично мне больше нравится последнее (видимо, последнее прижизненное для Ритчи) издание их книжки с Керниганом — разумеется, за вычетом приложения, в котором авторы явно нехотя рассказывают о возможностях, закреплённых стандартом ANSI. При этом сами они даже const в примерах не используют.

В принципе, лично я под «языком Си» для себя подразумеваю тот язык, который используется в этой книжке, плюс — таки да — модификатор const. Это тоже спецификация, и она ничем не хуже «K&R C». Можно было бы дать ей какое-нибудь название, как и всем другим известным спецификациям, и чтобы разработчики компиляторов перечисляли спецификации, которые данный конкретный компилятор поддерживает. От ANSI C это отличается, например, тем, что при присваивании указателю на функцию имени функции обязательно использовать операцию взятия адреса, а при вызове функции через указатель — операцию разыменования (лично я никогда эти операции не опускаю при работе на чистом Си, несмотря на то, что ASNI C это позволяет).

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

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

Ну почему же, спецификация, известная как K&R — не единственная существующая спецификация Си. Лично мне больше нравится последнее (видимо, последнее прижизненное для Ритчи) издание их книжки с Керниганом — разумеется, за вычетом приложения, в котором авторы явно нехотя рассказывают о возможностях, закреплённых стандартом ANSI. При этом сами они даже const в примерах не используют.

Имеется в виду условный ANSI C89? Почему тогда не их plan9 C?

От ANSI C это отличается, например, тем, что при присваивании указателю на функцию имени функции обязательно использовать операцию взятия адреса, а при вызове функции через указатель — операцию разыменования (лично я никогда эти операции не опускаю при работе на чистом Си, несмотря на то, что ASNI C это позволяет).

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

int a[] = {
 1, 2, 3
};
int *ap = a;

int f() {
 return 10;
}
int (*fp)() = f;

printf("%d %d\n", a[1], ap[1]);
printf("%d %d\n", f(), fp());

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

Так писать то на каком языке в итоге? ./configure.sh не только для библиотек, но и для фич языка использовать(: ?

Вот даже хеловорд ничем кроме plan9 компилятора скорее всего не собрать.

#include <u.h>
#include <libc.h>

void
main()
{
    print("hello, world\n");
    exits(0);
}
На сколько я знаю, стандарты С во многом лишь закрепляли то, что до этого было в основных компиляторах реализовано.

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

А какие-нибудь причины для этого есть?

Разумеется, есть: наглядность. Сама функция и указатель на неё — это не одно и то же. Вызов функции через указатель и её же вызов по имени — операции по сути разные.

(На всякий случай — к C++ сказанное неприменимо, но C++ — это другой язык)

Кроме того, в стандарте оба варианта.

Совершенно верно. Именно поэтому я не готов сказать, что спецификация, именуемая ANSI C, есть то, на чём я пишу. Поскольку там есть неприемлемые для меня вещи, в том числе вот это.

Так писать то на каком языке в итоге?

Видимо, на таком, который больше нравится.

./configure.sh

Autoconf/autotools — не использовать ни для чего и никогда, а от тех, кто использует, держаться подальше.

Но, на самом деле, тут, похоже, имеется путаница с обсуждаемым предметом. Это не программу нужно адаптировать к компиляторам, а наоборот — для программы указывать множество компиляторов, которые для неё годятся.

На сколько я знаю, стандарты С во многом лишь закрепляли

Для ANSI C это было с натяжкой верно. Уже для C99 — нет; там толпа идиотов протащила в стандарт пачку таких расширений, которые если и существовали, то где-то непонятно где и непонятно зачем. Я, кстати, не уверен, что L"abc" вообще хоть где-то существовало до его появления в стандарте. А потом, купившись на слово «стандарт» и забыв, что технические стандарты никогда не бывают нормативными, разработчики компиляторов принялись всё это имплементить — но, кстати, тоже не все и не всегда; прошло почти десять лет, пока вроде бы C99 стали поддерживать _большинство_ компиляторов, а не отдельные маньяки типа gcc.

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

Сама функция и указатель на неё — это не одно и то же. Вызов функции через указатель и её же вызов по имени — операции по сути разные.

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

Именно поэтому я не готов сказать, что спецификация, именуемая ANSI C, есть то, на чём я пишу. Поскольку там есть неприемлемые для меня вещи, в том числе вот это.

Подмножество ANSI C — это все равно ANSI C.

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

Это же бардак. Нужно иметь по 10 компиляторов для каждой архитектуры?

Уже для C99 — нет; там толпа идиотов протащила в стандарт пачку таких расширений, которые если и существовали, то где-то непонятно где и непонятно зачем.

Из вики:

  • Встраиваемые функции (объявленные с ключевым словом inline). # gcc -std=gnu89
  • Место, в котором возможно объявление переменных, больше не ограничено глобальной областью видимости и началом составного оператора (блока). # gcc -std=gnu89
  • Несколько новых типов данных, включая long long int, дополнительные расширенные целые типы, явный логический тип данных, а также комплексный тип (complex) для представления комплексных чисел. # gcc -std=gnu89
  • Массивы переменной длины (variable-length arrays). # gcc -std=gnu89
  • Поддержка однострочных комментариев, начинающихся с //, как в BCPL или C++. # gcc -std=gnu89
  • Новые библиотечные функции, как, например, snprintf.
  • Новые заголовочные файлы, такие как stdbool.h и inttypes.h.
  • Типовые математические функции (tgmath.h).
  • Улучшена поддержка стандарта IEEE 754-2008.
  • Проектируемые инициализаторы.
  • Составные константы (например, стало возможным определять структуры прямо в вызове функции: function((struct point){4,2})). # gcc -std=gnu89, и, емнип, в plan 9
  • Поддержка вариативных макросов (макросов переменной арности). # gcc -std=gnu89 Смягчение (restrict) ограничений для более агрессивной оптимизации кода. # gcc -std=gnu89 в виде __restrict

Я, кстати, не уверен, что L"abc" вообще хоть где-то существовало до его появления в стандарте.

В plan 9 было.

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

Это же бардак. Нужно иметь по 10 компиляторов для каждой архитектуры?

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

Подмножество ANSI C — это все равно ANSI C.

Подмножество, полученное убиранием элементов (так называемое строгое подмножество), никогда по определению не равно исходному множеству. С таким же успехом можно сказать, что чистый Си — это тоже Си++.

Из вики:

Из всего этого относительно полезны разве что inline и snprintf (но snprintf — это просто библиотечная функция, в норме это вообще не должно иметь никакого отношения к спецификации _языка_). Всё остальное либо бесполезно (как описания переменных где попало), либо вредно (stdbool.h), но большинство пунктов просто-таки катастрофично (VLA, wchar_t, L"abc", _Complex).

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

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

Конкуренция — это когда любую прогу можно скомпилить любым компиляторам. Ну +-. А когда под каждую прогу на одном языке нужен строго определенный компилятор — это бардак(:

Подмножество, полученное убиранием элементов (так называемое строгое подмножество), никогда по определению не равно исходному множеству. С таким же успехом можно сказать, что чистый Си — это тоже Си++.

Я и не говорю, что равно. Код, распознается корректным парсером ANSI C — это код ANSI C. Даже если это int main(){ return 0; }.

К слову, С не подмножество С++.

Из всего этого относительно полезны разве что inline и snprintf (но snprintf — это просто библиотечная функция, в норме это вообще не должно иметь никакого отношения к спецификации _языка_).

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

либо вредно (stdbool.h), но большинство пунктов просто-таки катастрофично (VLA, wchar_t, L"abc", _Complex).

А что плохого в bool, VLA, _Complex, нелатинских буквах?

deadskif
()

Спасибо автору за сей труд. Аккурат нужный вектор книги.Ждем-с новые тома.

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

Конкуренция — это когда любую прогу можно скомпилить любым компиляторам.

Не бывает. Невзирая ни на какие стандарты. Невозможно принципиально.

Ну +-. А когда под каждую прогу на одном языке нужен строго определенный компилятор — это бардак

Почему «строго определённый»? Любой, поддерживающий данную спецификацию. Если данную конкретную спецификацию поддерживает ровно один компилятор, то придётся использовать его.

NB: для Паскаля вон вообще ни одного используемого стандарта нет, и ничего, как-то он живёт. Хотя там жёстко каждая программа привязана к тому компилятору, под который написана.

Код, распознается корректным парсером ANSI C — это код ANSI C. Даже если это int main(){ return 0; }.

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

К слову, С не подмножество С++.

Ну строго говоря да, не подмножество. Ну хорошо, можно выделить пересечение множеств C и C++ (то есть C за вычетом тех конструкций, которые не годятся для C++, таких как typedef s1 {/*...*/} s1;) и заявить, что это C++. По-моему, получится бред.

И таки С без стандартной библиотеки — сферический конь в вакууме, как на нем писать?

Как писать? Как люди пишут ядра операционных систем? (разумеется, там нет стандартной библиотеки и не может быть) Как люди (например, вроде меня) пишут всякие прошивки микроконтроллеров? (разумеется, никакой стандартной библиотеки, чур меня)

Вот как раз C в связке со стандартной библиотекой — явление не вполне понятное, то есть лично мне так и остаётся непонятным, накой чёрт на этом удолбище писать, когда есть много других языков. А в тех двух (прописью — двух) ситуациях, когда языку Си нет альтернативы, стандартная библиотека (surprize!) не используется и использоваться не может.

А что плохого в bool, VLA, _Complex, нелатинских буквах?

bool просто не нужен, он не даёт никакой пользы. При этом программа, написанная с его использованием, будет компилироваться мЕньшим количеством компиляторов. Ну и ради чего тогда?

_Complex может и должен быть реализован полностью на уровне библиотеки, причём НЕ стандартной — комплексная арифметика требуется в крайне малом количестве ситуаций, и, насколько я могу судить, НИКОГДА не требуется в системных программах, то есть это просто специфическая предметная область, не более того; нельзя в стандарт языка втюхивать поддержку каждой под руку попавшейся предметной области.

Про недопустимость non-ascii chars в исходных текстах программ (вне зависимости от используемого языка программирования) см. здесь: http://www.stolyarov.info/books/codestyle начиная со стр.18. Вообще, юникод в любой своей ипостаси — это не текст, это бинарный формат для пусть и распространённой, но частной предметной области. В языке такому не место заведомо, и уж тем более нельзя допускать наличие в языке конструкций, провоцирующих использование такого кодинг-стайла, за который надо увольнять с работы (в данном случае — non-ascii chars).

Ну а про VLA мне, честно говоря, странно, что вообще есть люди, задающие этот вопрос всерьёз. Ответ, например, есть здесь: http://www.stolyarov.info/node/187#comment-983 и повторять эти (на мой взгляд, абсолютно очевидные) вещи я больше не хочу.

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

Не бывает. Невзирая ни на какие стандарты. Невозможно принципиально.

Не, понятно, что это идеализм, но многие ANSI C проги нормально собираются многими ANSI C компиляторами.

Почему «строго определённый»? Любой, поддерживающий данную спецификацию. Если данную конкретную спецификацию поддерживает ровно один компилятор, то придётся использовать его.

Так сейчас так и есть. Просто спецификацю ANSI C поддерживает большинство современных компиляторов. gnu-тые расширения тоже многие имеют в виду.

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

Вопрос живости паскаля (особенно в FOSS и *nix) крайне дискуссионный (=. По-вашему, такая привязка — это не плохо?

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

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

#include <stdio.h>
int main() {
    printf("Hello ANSI C\n");
    return 0;
}
Это ANSI C?

Ну хорошо, можно выделить пересечение множеств C и C++ (то есть C за вычетом тех конструкций, которые не годятся для C++, таких как typedef s1 {/*...*/} s1;) и заявить, что это C++. По-моему, получится бред.

Да, это С++ фактически, хоть и наверняка не идиоматический. А так же С и вроде как Obj-C и Cyclone.

#include <stdio.h>
#define sub int
#define print(a) printf("%s", a)
sub main() {
    print("Hello world\n");
}

#ifdef _perl
main();
#endif

Это какой язык(: ?

Как писать? Как люди пишут ядра операционных систем? (разумеется, там нет стандартной библиотеки и не может быть) Как люди (например, вроде меня) пишут всякие прошивки микроконтроллеров? (разумеется, никакой стандартной библиотеки, чур меня)

Ну вообще на С пишут не только это. И обычного userspace софта на С написано очень много. Его как писать?

Вот как раз C в связке со стандартной библиотекой — явление не вполне понятное, то есть лично мне так и остаётся непонятным, накой чёрт на этом удолбище писать, когда есть много других языков. А в тех двух (прописью — двух) ситуациях, когда языку Си нет альтернативы, стандартная библиотека (surprize!) не используется и использоваться не может.

Вопрос выбора С в качестве языка для софта опять же дискуссионный. Тем не менее факт, на С дорабатывают и пишут много кода. *nix без libc будет нечто совсем другое.

bool просто не нужен, он не даёт никакой пользы. При этом программа, написанная с его использованием, будет компилироваться мЕньшим количеством компиляторов. Ну и ради чего тогда?

Примерно для того же, для чего и enum-ы, наверно. + большая унификация с плюсами, возможно. В паскале прибитость к одному компилеру вас не смущает, а тут это лечится элементарным stdbool.h в include path.

stdint.h тоже вреден, по вашему?

Complex может и должен быть реализован полностью на уровне библиотеки, причём НЕ стандартной — комплексная арифметика требуется в крайне малом количестве ситуаций, и, насколько я могу судить, НИКОГДА не требуется в системных программах, то есть это просто специфическая предметная область, не более того; нельзя в стандарт языка втюхивать поддержку каждой под руку попавшейся предметной области.

Согласен. Поэтому в С11 его сделали опциональным.

Про недопустимость non-ascii chars в исходных текстах программ (вне зависимости от используемого языка программирования) см. здесь: http://www.stolyarov.info/books/codestyle начиная со стр.18. Вообще, юникод в любой своей ипостаси — это не текст, это бинарный формат для пусть и распространённой, но частной предметной области. В языке такому не место заведомо, и уж тем более нельзя допускать наличие в языке конструкций, провоцирующих использование такого кодинг-стайла, за который надо увольнять с работы (в данном случае — non-ascii chars).

Использовать gettext, что бы вывести «λ =» в своем велосипеде? ОК. А юникод, это текст. Как вы предлагаете его корректно обрабатывать? Сторонними несовместимыми библиотеками?

Ну а про VLA мне, честно говоря, странно, что вообще есть люди, задающие этот вопрос всерьёз. Ответ, например, есть здесь: http://www.stolyarov.info/node/187#comment-983 и повторять эти (на мой взгляд, абсолютно очевидные) вещи я больше не хочу.

Аргумента я там увидел 2. 1. Использование _может_ привести к неприятным последствиям, если использовать не аккуратно. Так это практически со всем в С так. 2. Применение alloca — результат обдумывания, применение VLA — результат нежелания думать. Чет как то очень спорно.

deadskif
()

Цитата из книги:

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

cd Photoalbum/2015 
mkdir Paris 
cd Paris
mount /mnt/flash 
cp /mnt/flash/dcim/* . 
umount /mnt/flash

Разве это не пример задачи, которую проще сделать в графике? Как минимум на фотике будут старые фотографии и нужно увидеть превью, чтобы скопировать только новые. Но даже если на фотике только нужные фотки, то спорно что копирование будет быстрее через консоль.

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

P.S А зачем защита от копирования? Удобно ведь скопировать нужные куски текста для заметок или какой-то код.

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

Разве это не пример задачи, которую проще сделать в графике?

Нет.

Как минимум на фотике будут старые фотографии и нужно увидеть превью, чтобы скопировать только новые.

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

спорно что копирование будет быстрее через консоль.

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

P.S А зачем защита от копирования?

Это защита не от копирования, а от смены формата. Копировать, как можно заметить, вы этот файл можете сколько угодно, он не перестанет от этого читаться, ничего похожего на DRM там нет и быть не может. Но вот против появления в Сети версий моей книги, представленных в любых редактируемых формах, включая plain text, я категорически возражаю, и как показала практика (вот хоть на первую страницу комментов гляньте прямо здесь) просто написать «не делайте так» недостаточно, приходится ставить хотя бы простенький, но всё же технический барьер.

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

Как люди пишут ядра операционных систем? (разумеется, там нет стандартной библиотеки и не может быть)

Вот как раз C в связке со стандартной библиотекой — явление не вполне понятное

bool просто не нужен, он не даёт никакой пользы

_Complex может и должен быть реализован полностью на уровне библиотеки, причём НЕ стандартной

Ну а про VLA мне, честно говоря, странно, что вообще есть люди, задающие этот вопрос всерьёз

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

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

gnu-тые расширения

Вот, кстати, это скорее в мою пользу аргумент. У стандартизаторов, конечно, мозги не на месте, но их хватает на то, чтобы расширения gnu в стандарты не включать. При этом сами эти расширения продолжают существовать, несмотря на свою абсолютную, беспредельную, феерическую чудовищность (взять хотя бы вложенные функции).

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

*nix без libc будет нечто совсем другое.

Подозреваю, *nix без libc будет эффективнее и удобнее. Ну то есть если про glibc говорить, то тут вообще без вариантов, этот монстр и так прожил лет на десять дольше, чем должен был, и сейчас его какой-нибудь musl или ещё кто-то подобный задавит без вариантов, но по мне так даже и musl прямо со старта слишком сложен — я, например, совершенно не понимаю, почему я должен терпеть мьютексы внутри malloc, при том что я никогда (принципиально никогда) не использую малтитрединг, как и большинство людей, пишущих на Си — но всё это большинство вынуждено расплачиваться за существование тредов, которые нужны только макакам, не умеющим мыслить в терминах явных состояний.

С musl'ом, в принципе, всё как раз понятно, его создатели ставили перед собой цель поддержать совместимость с другими вариантами libc, чтобы можно было ничего не менять в исходнике и при этом отказаться от glibc в пользу musl. Но вот если таких целей перед собой не ставить, вырисовывается совершенно другая библиотека, в которой, например, в printf/* работают только те преобразования, которые нужны в данной конкретной программе (а код остальных преобразований в бинарник не попадает), в которой multithread safety появляется только в случае, если в линковку вставить pthread, и так далее.

Примерно для того же, для чего и enum-ы, наверно

Вот уж точно нет. От enum'ов есть несомненная польза — если в программе встречено число 13, то понять, чтО имеется в виду, может оказаться совершенно нереально, тогда как если там будет имя, то всё будет понятно сразу и без усилий. Поэтому именованные константы, конечно же, нужны. enum'ы при этом лучше макросов, потому что подчиняются областям видимости.

Для логических значений сие не работает: все прекрасно знают, что 0 — это ложь, а всё остальное — истина. На этот примитивный случай всё сказанное про полезность enum'ов не распространяется.

лечится элементарным stdbool.h в include path.

Лечится что угодно. Просто это требует хоть каких-то, хоть примитивных, но всё же лишних движений от мейнтейнера, причём кодер-то один, а мейнтейнеров много; левая пятка кодера в какой-то момент возжелала писать true/false вместо 1/0, а расплачиваться за это приходится мейнтейнерам — иногда сотням таковых.

stdint.h тоже вреден, по вашему?

В том виде, в котором он сейчас есть — несомненно. Хотя, каюсь, сам использую :)

Использовать gettext, что бы вывести «λ =»

Куда вывести, на stdout? Руки отрывать за такое.

А юникод, это текст

Юникод в общем случае — это бинарник, такой же, как jpeg или mp3. Если когда-нибудь в Си (в самом языке) появится поддержка mp3, я думаю, на этом язык кончится.

Сторонними несовместимыми библиотеками?

Несовместимыми с чем, простите? Библиотеки оказываются несовместимы, только когда они зависят друг от друга. Ну так зависимость библиотек друг от друга недопустима, хотя не все это понимают. Само понятие dependency — это химически чистое зло.

Применение alloca — результат обдумывания, применение VLA — результат нежелания думать. Чет как то очень спорно.

Вот тут уж можете мне поверить. Многократно видел студентов, которые пытаются использовать VLA, потому что не понимают, что такое malloc (и вообще что такое указатель). Макака с компилятором Си — это ещё хуже, чем обезьяна с гранатой.

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

Вот, кстати, это скорее в мою пользу аргумент. У стандартизаторов, конечно, мозги не на месте, но их хватает на то, чтобы расширения gnu в стандарты не включать. При этом сами эти расширения продолжают существовать, несмотря на свою абсолютную, беспредельную, феерическую чудовищность (взять хотя бы вложенные функции).

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

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

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

Подозреваю, *nix без libc будет эффективнее и удобнее. Ну то есть если про glibc говорить, то тут вообще без вариантов, этот монстр и так прожил лет на десять дольше, чем должен был, и сейчас его какой-нибудь musl или ещё кто-то подобный задавит без вариантов, но по мне так даже и musl прямо со старта слишком сложен — я, например, совершенно не понимаю, почему я должен терпеть мьютексы внутри malloc, при том что я никогда (принципиально никогда) не использую малтитрединг, как и большинство людей, пишущих на Си — но всё это большинство вынуждено расплачиваться за существование тредов, которые нужны только макакам, не умеющим мыслить в терминах явных состояний.

С musl'ом, в принципе, всё как раз понятно, его создатели ставили перед собой цель поддержать совместимость с другими вариантами libc, чтобы можно было ничего не менять в исходнике и при этом отказаться от glibc в пользу musl. Но вот если таких целей перед собой не ставить, вырисовывается совершенно другая библиотека, в которой, например, в printf/* работают только те преобразования, которые нужны в данной конкретной программе (а код остальных преобразований в бинарник не попадает), в которой multithread safety появляется только в случае, если в линковку вставить pthread, и так далее.

Осталось написать такую библиотеку. Но вы таки не объяснили, как писать обычный userspace софт без libc?

Вот уж точно нет. От enum'ов есть несомненная польза — если в программе встречено число 13, то понять, чтО имеется в виду, может оказаться совершенно нереально, тогда как если там будет имя, то всё будет понятно сразу и без усилий. Поэтому именованные константы, конечно же, нужны. enum'ы при этом лучше макросов, потому что подчиняются областям видимости.

Для логических значений сие не работает: все прекрасно знают, что 0 — это ложь, а всё остальное — истина. На этот примитивный случай всё сказанное про полезность enum'ов не распространяется.

enum-ы еще и явно задают возможные значения, так что это немного нагляднее.

int blabla0;
enum blabla blabla1;
bool blabla2;

а расплачиваться за это приходится мейнтейнерам — иногда сотням таковых.

Вот скажите честно, что это за сотни мейнтейнеров, и чем таким, не поддерживающим stdbool, они собирают?

Юникод в общем случае — это бинарник, такой же, как jpeg или mp3. Если когда-нибудь в Си (в самом языке) появится поддержка mp3, я думаю, на этом язык кончится.

В таком контексте, любой текст в общем случае — это бинарник.

Несовместимыми с чем, простите?

Несовместимыми между собой. В итоге разные программы работают с разными библиотеками для базовой обработки plain text в unix. Ну разве это не ад?

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

И как предполагается в библиотеке А использовать функциональность библиотеки Б?

Многократно видел студентов, которые пытаются использовать VLA, потому что не понимают, что такое malloc (и вообще что такое указатель). Макака с компилятором Си — это ещё хуже, чем обезьяна с гранатой.

Ну блин, студенты и макаки найдут еще 100500 способов выстрелить себе сразу в голову. Это не проблемы Си.

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

Брр s:/единственным широко распространенным языком/единственным широко распространенным свободным компилятором/

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

Отнюдь. Живут они по следующим причинам:

1) Без их поддержки не удастся использовать заголовки glibc, использующейся в подавляющем большинстве дистрибутивов Linux

2) Они используются в коде ядра Linux

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

``Живут" в смысле их не выкидывают из gcc и других копмилеров или в смысле их используют без особых причин в несвязанном с этими вариантами кодом?

Есть, кстати, какая-нибудь статистика по распространенности gcc-измов в проектах?

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

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

Ну так вы же сами ратовали за ``больше разных диалектов C".

Ничего подобного. Я ратовал за отсутствие бумажек, на которых написано «стандарт». Многообразие диалектов — это даже не следствие, это просто реальность, на которую, как видим, стандарты повлиять не в состоянии. И то обстоятельство, что я не приемлю стандарты, не означает, что мне именно что _нравится_ наличие заведомо ублюдочных диалектов Си, я лишь констатировал факт, что стандарты не мешают таким диалектам появляться.

Интересно, что такого ужасного во вложенных функциях?

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

Попробуйте, например, осознать машинную команду ENTER с ненулевым вторым операндом и то, как ею нужно пользоваться при реализации этих вот вложенных функций. Можно и с другой стороны зайти: смысл вложенных функций в том, что из их тел есть доступ к локальным переменным объемлющей функции. Теперь представьте себе, как это всё должно быть реализовано. Причём не в Лиспе каком-нибудь, где есть лексические контексты, замыкания и прочие пляски, а в низкоуровневом языке, каковым является Си.

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

GCC
языком

Вы же пошутили, да?

Но вы таки не объяснили, как писать обычный userspace софт без libc?

На сисколлах, на сисколлах. Подождите выхода второго тома, там про это будет целая глава.

Вот скажите честно, что это за сотни мейнтейнеров, и чем таким, не поддерживающим stdbool, они собирают?

Вот непосредственно только что специально зашёл на свой сервак под Openwall Linux, посмотрел в /usr/include, там этого stdbool нет. Следовательно, любая программа, которая его использует, сходу под Openwall не соберётся. А мне собирать пакеты под Openwall приходится достаточно часто для того, чтобы желать смерти от поноса всем, кто не отличается разборчивостью в выборе инструментов.

И как предполагается в библиотеке А использовать функциональность библиотеки Б?

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

Между прочим, моя точка зрения ещё не самая экстремальная. Тут на LORе недавно проскакивало руководство по кодингу, вообще запрещающее использование любых сторонних библиотек. Если подумать, в этом тоже есть некая сермяжная правда: кодер, втаскивающий в проект огромную либу ради какой-нибудь мелкой функции, совершенно не думает о том, как потом эту либу будут за собой таскать десятки, а то и сотни людей, которым придётся иметь дело с его кодом.

Ну блин, студенты и макаки найдут еще 100500 способов выстрелить себе сразу в голову. Это не проблемы Си.

Минуточку, мой исходный тезис состоял в том, что использование alloca есть результат обдумывания, а использование VLA — результат нежелания думать. Приведённый пример это наглядно показывает. VLA — это, таки да, инструмент для макаки и, более того, поощряющий макаковое мышление. Это, конечно, не единственный недостаток VLA и даже, возможно, не главный, но он тоже есть.

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

упс, ещё один перл не заметил

В таком контексте, любой текст в общем случае — это бинарник.

Ничего похожего. ASCII-текст — это текст, а всё остальное — это бинарник. Подробности см. в обсуждаемой книжке, параграф 1.6.5.

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

Кстати, вот ещё про вложенные функции: https://gcc.gnu.org/onlinedocs/gccint/Trampolines.html

Если кто не понял, оно располагает трамплин прямо в стеке и, как следствие, не работает при non-executable stack. И всё это мракобесие — только для того, чтобы безалаберные макаки могли написать одну функцию внутри другой.

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

Ничего подобного. Я ратовал за отсутствие бумажек, на которых написано «стандарт». Многообразие диалектов — это даже не следствие, это просто реальность, на которую, как видим, стандарты повлиять не в состоянии. И то обстоятельство, что я не приемлю стандарты, не означает, что мне именно что _нравится_ наличие заведомо ублюдочных диалектов Си, я лишь констатировал факт, что стандарты не мешают таким диалектам появляться.

Вы боитесь слова ``стандарт"? Чем наличие определенного диалекта, который стараются поддерживать большинство компиляторов хуже ситуации, когда все делают что хотят?

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

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

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

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

Вы же пошутили, да?

Ниже поправился.

На сисколлах, на сисколлах. Подождите выхода второго тома, там про это будет целая глава.

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

Вот непосредственно только что специально зашёл на свой сервак под Openwall Linux, посмотрел в /usr/include, там этого stdbool нет. Следовательно, любая программа, которая его использует, сходу под Openwall не соберётся.

# gentoo
$ ls /usr/include/stdbool.h
ls: невозможно получить доступ к /usr/include/stdbool.h: Нет такого файла или каталога
$ find /usr/lib/gcc/x86_64-pc-linux-gnu/ -name "stdbool.h"
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/stdbool.h
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/include/g++-v4/tr1/stdbool.h

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

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

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

Если подумать, в этом тоже есть некая сермяжная правда: кодер, втаскивающий в проект огромную либу ради какой-нибудь мелкой функции, совершенно не думает о том, как потом эту либу будут за собой таскать десятки, а то и сотни людей, которым придётся иметь дело с его кодом.
огромную либу ради какой-нибудь мелкой функции

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

Минуточку, мой исходный тезис состоял в том, что использование alloca есть результат обдумывания, а использование VLA — результат нежелания думать. Приведённый пример это наглядно показывает.

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

Ничего похожего. ASCII-текст — это текст, а всё остальное — это бинарник.

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

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

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

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