Pull to refresh

Comments 114

Да не то слово. У Страуструпа совершенно неповторимый стиль письма, читать его — почти наслаждение. Читаешь и как бы представляешь себе убеленного сединами дзен-старца, сидящего напротив и неспешно рассказывающего тебе притчи за чашкой чая. С одной стороны, все разжевано, но с другой — не чрезмерно, а в самый раз, и даже веет некоторым академическим духом. Как он так умудряется, непонятно.

Что касается смысловой части моего комментария, то я рекомендую всем, кто не читал его монументальный труд по C++, сделать это, даже если вы никогда не писали ранее на C++, а пишете на Java, Python, PHP и т.д. Купите в магазине бумажную версию на русском языке, я обещаю — получите массу удовольствия.
… да, я еще хочу добавить, что Страуструп — мужик уникальный. Ниже было сравнение с Виртом и замечено, что Вирт в конце заскакал галопом по европом и забросил все свои языки. Может быть, это связано с возрастом — седина в бороду, старческий склероз и т.д. А вот Страуструп взвалил на себя и все эти годы тянет такую огромную МАХИНУ… И ни намека на забрасывание. Я восхищаюсь тем, как у него эта махина даже просто помещается в голове. Ведь C++ — сложнейший язык (наверное, самый сложный из существующих?), и ведь все так построено, что его сложность реально оказывается оправданной (это при наличии-то кучи других, более простых языков вокруг). И он не коллапсирует под собственным весом, возможно, благодаря усилиям Страуструпа.
Я восхищаюсь тем, как у него эта махина даже просто помещается в голове.

Ну, по признанию Страуструпа он знает язык на 7-8 из 10ти… Так что — не совсем уже помещается :)
Зашёл в предвкушении почитать холивар согласчных и не согласных, но поняв, что это перевод Страуструпа… вообщем не стоило запасаться поп-корном…
Да уж, я тоже ближе к середине статьи начал чувствовать неладное: скепсис постепенно улетучивается, а ладони сами собой складываются на груди в молебную лодочку. Думаю, вот это автор жжет. А потом смотрю — это ж памятник Страуструп…
А я все-таки подкину холивора к переводу:
миф 1; с использованием getchar(), isdigit() можно написать то, что будет быстрее против «полноценного» iostream.
(и да, в iostream внутри где-то была глобальная блокировка… вокруг разных кодировок, что ли? неважно, оно и так медленно).
миф 5: для таких задач есть perl. Для промежуточных задач есть perlembed. Не надо писать небольшие программы на C++, он недружелюбен к маленьким юзерским задачам.
миф 1; с использованием getchar(), isdigit() можно написать то, что будет быстрее против «полноценного» iostream.
(и да, в iostream внутри где-то была глобальная блокировка… вокруг разных кодировок, что ли? неважно, оно и так медленно).

Статья ж про это была на хабре меньше месяца назад. Там и сравнение было по скорости выполнения.
В С-версии необходимо напрямую работать с символами и памятью:

Ну, для таких задач есть snprintf/asprintf, как мне кажется.
Аналогом может быть только функция с сигнатурой
char * concat(const char *, const char *, ...);

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

Благодаря С++11, С++ стал более дружественным для новичков.

А давайте всё-таки сжалимся над новичками? Что си, что плюсы — отвратительные языки для обучения программированию. Вот в коде для плюсов используется const string& в качестве аргументов для конкатенации. Что вы ответите на вопросы новичка «что такое const» и «и что такое &»?

Приведённый код на C более длинный, но он примитивный, состоит из простых кирпичиков. Объяснить его гораздо проще. Примитивную реализацию strlen и strcpy даже показать можно. Никакой магии. То есть если припрёт обучать относительно низкоуровневому коду, но С как раз подходит лучше.

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

Прекрасное обобщение, ничего не добавить.

Миф 3: В надёжных программах необходима сборка мусора

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

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

В плюсах тьма фич для управления памятью. При использовании любой из них очень просто допустить ошибку. Ну и где доказательство надёжности для опровержения мифа?
Да как вы посмели возражать Страуструпу?!
C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.
Приведённый код на C более длинный, но он примитивный, состоит из простых кирпичиков. Объяснить его гораздо проще. Примитивную реализацию strlen и strcpy даже показать можно. Никакой магии. То есть если припрёт обучать относительно низкоуровневому коду, но С как раз подходит лучше.


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

Ну и где доказательство надёжности для опровержения мифа?

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

Читал недавно Мейерса. Эффективный С++14.
Таки я считаю что для новичка это далеко не лучший язык (сам начинал именно с него и много страдал). Да, const, & — по началу весьма непонятно (хотя, нет, вру, как раз const как таковой не вызывал у меня вопросов в параметрах, мне не понятно было зачем его пихать везде. И что значит const после прототипа функции.).

«вызов виртуальной функции препятствует инлайнингу, что может раз в 50 замедлить вашу программу»
Для тех кто плохо знаком с внутренней кухней это «хрмбрмрмрбхппхх», однозначно! :)

А вот насчет управления памяти и жизнью объектов с вами не соглашусь. Для меня — то что компилятор САМ позаботится о деструкторах, и есть «автоматически», а не вручную. Я пишу на плюсах 10 лет, из них 4 года в коммерческой разработке (нет, не такой большой опыт, кто спорит), но я уже давно не заморачиваюсь «управлением памятью».
Контейнеры, shared-поинтеры, передача this в качестве parent в Qt — все это разные ипостаси RAII, и я не знаю как при любой из них «просто допустить ошибку». Да, ошибки допустить МОЖНО. С++ позволяет допускать ошибки (например, создать указатель и передать его в конструкторы разных shared_ptr), но это же постараться надо =)

Т.е., подытожив — в современных плюсах РУЧНОЕ управление памятью есть, но оно нафиг обычно не нужно.
> новичкам про что такое const и &

const — гарантия неизменения состояния объекта
& — работа непосредственно с передаваемым экземпляром, без копирования

?

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

std::string hello("Hello");
std::string world("world!");

hello + " world!";  // ok
"Hello" + world;    // ok
"Hello" + " world"; // ERROR

Ладно, сложение строковых литералов это боян. Давайте попробуем свежачок.

// ok
std::array<int, 5> int_array = {1, 2, 3, 4, 5};

struct IntPair { int first; int second; };

// ERROR, WTF?!!!
std::array<IntPair, 2> int_pair_array = {{0,0}, {100,100}};

//ok
std::array<IntPair, 2> int_pair_array2 = {{{0,0}, {100,100}}};
Воу,
too many initializers
? Какого чёрта?
Это потому что std::array является аггрегатом, у него вообще нету пользовательских конструкторов (в том числе и конструктора, принимающего std::initializer_list). Этот код аналогичен такому (кстати, в вышеприведенном коде не указана длина массивов, так что второй ok на самом деле не ok):
struct array_type {
    IntPair data[5];
};

array_type int_pair_array = {{0,0}, {100,100}};

Раз std::array является аггрегатом, то при инициализации с помощью фигурных скобочек происходит aggregate initialization. А она смотрит, что внутри две пары фигурных скобок, а член данных у аггрегата только один (массив data), и поэтому выдает ошибку компиляции.
Спасибо за объяснение. У меня вопрос: то, как Вы это поняли — это результат уже опыта, или где-то прочитали, или прочитали && скомбинировали && догадались?
Вот еще хороший боян, который без экскурса в си ( или скорее в асм ) объяснить будет непросто.
// ok
switch(x){ case 3: }; 

// oops
std::string s;
switch (s) { case "3":};
Объяснить-то можно очень просто: нежелание комитета по стандартизации ломать стереотип «switch компилируется в очень эффективный код», а также делать синтаксис ещё более монструозным. Я положительно не вижу причин, почему
    std::string s;
    switch (s)
    {
    case "1":
        something;
    case "2":
        another_thing;
    }
    // ...
нельзя компилировать в
    std::string s;
    if (s == std::string("1"))
        goto case_1;
    else if (s == std::string("2"))
        goto case_2;
    else
        goto case_end;
case_1:
    something;
case_2:
    another_thing;
case_end:
    // ...
Но ведь обязательно найдётся человек, которого operator==() не устроит, для которого надо будет выдумывать поддержку
switch <[](auto x, auto y){ return x.foo == y.bar; }> (s)
{
case zog:
    // ...
}
Только вот switch и string немного не дружат :)
Имху, костыль, да, груз совместимости. Но он мне тоже нравится. Если очень хочется, можно переопределить оператор для сложения строк. (может быть даже, в бусте есть для этого заголовочный файл, хотя есть риск что-то отломать). А в одном из новых стандартов мб есть что-то для компактного инплэйс создания константных std::string вместо const char[].

А еще для меня все это выглядит логично. Складывать char* нельзя, если хочешь складывать — пользуешься std::string. При этом я не вижу в использовании std::string чего-то языкового. Это, хоть и стандартная, но библиотека, и имеет свои семантические границы.

Свежачок заставил задуматься. Мне, на самом деле, не очень понятна суть list initialization (я про них почти не смотрел). Но, если бы код писал я, я писал бы
std::array<IntPair, 2> int_pair_array = {(IntPair){...}, (IntPair){}}

То что иногда можно не писать тип перед {}, это, вроде, скорее приятное исключение. (как в составе = { })
Если очень хочется, можно переопределить оператор для сложения строк.
Операторы можно переопределять только для пользовательских типов; std::string + (char *) или (char *) + std::string OK, (char *) + (char *) нельзя.
const — гарантия неизменения состояния объекта
& — работа непосредственно с передаваемым экземпляром, без копирования


А зачем это знать при начальном обучении? Старый, прости господи, фортран, передавал все переменные по ссылке, так что они сквозные в каждой процедуре. Это позволяет (сама концепция, не язык) объяснять принципы программировани без размена на детали.
Вот потом уже можно рассуждать о том, вот при таком-то неудачном использовании можно случайно поменять этот объект, а чтобы такого не было, защитим его const'ом.

Со ссылками и указателями аналогично — это детали низкого уровня. (еще отличия от передачи по ссылке и указателю кроме синтаксиса) Что проще новичку:

abc(a, b)

a = b + 3

или объяснение про передачу с использованием указателя и почему мы не можем поменять a напрямую, если нам надо?
Си++ как первый язык плох уже тем, что новичок не понимает зачем си++ решает те или иные задачи, так как не писал на голом си.
А вот если сперва набить шишек на всех этих malloc/realloc/free, на закытии файлов/сокетов и тд, вот тогда начинаешь ценить деструкторы, конструкторы копирования и умные указатели. Да и глупых ошибок с присовоенем одного указателя двум разным объектам умных указателей уже не возникает.
Учить же с++ как первый — взырв мозга. Слишком много концепций, тонкостей, исключений, разных подходов ( например смесь cout и printf в коде ).
Согласен с вами. Без экскурса в историю о том, что C++ появился из Си, обычно не так просто объяснить, почему, например, scanf не работает с std::string.
Читаю Вас Всех, и честно — не понимаю. Кратко про себя: {Школа -> Basic} + {Институт -> Pascal} + {практика -> С}. Без всякого предварительного изучения нужно было читать программы на C. Пришлось разбираться на месте. Я, если честно до мозга и костей проникся любовью к скобкам{} /инкременту ++/декременту --/то, что переменные нет необходимости объявлять заранее/к оператору return и пр. Потом С++ изучал из собственного любопытства. Дальше работа. Угадаете на каком языке пишу?
Вот за весь этот путь я ни разу не оглянулся и не сказал: «какой сложный язык! А вот в Delphi/Java/C# бла-бла-бла на Ваш вкус». Может тут не все отлавливают 45% ошибок еще на этапе компиляции, а еще 50% во время первых отладок? Оставшиеся 5% это явно не проблема языка и все те, кто занимается разработкой хотя бы лет 5, это понимают.

Подытожу: сложности и нюансы есть в любом языке. Вы конечно можете дать новичку пример со строками, как выше, только у меня есть один вопрос — а зачем новичку это показывать? Или может быть в других языках нет операций взятия адреса или спецификатора const? Почему, если произносятся 2 слова в одном предложении — «новичок + изучать», то все сразу думают про школу/институт/первый язык программирования? Как насчет тех, кому просто необходимо изучить C++?
Или может быть в других языках нет операций взятия адреса или спецификатора const?

Не во всех есть. В том же Бейсике нет. В паскале не помню, есть ли const.

о все сразу думают про школу/институт/первый язык программирования?

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

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

Вот за весь этот путь я ни разу не оглянулся и не сказал: «какой сложный язык! А вот в Delphi/Java/C# бла-бла-бла на Ваш вкус».

Мой путь: {Школа: Logo, C, C++} -> {Универ: Pascal, Delphi, PHP, SQL, JS, C++} -> {Практика: C++, C#}. Уверяю, начинать с плюсов — это не самая лучшая идея. :) Хотя я тоже полюбил скобочки, инкременты и прочее, это была боль. И потом понимаешь, что можно было проще.
Полагаю такую историю может рассказать почти каждый из отметившихся в этом топике. Дело ведь не в том как вам или мне удалось разобраться и продраться через трудности ( о которых тогда возможно и не подозревали ). А в том какой ЯП будет наиболее оптимальным для начального изучения. Я вот тоже начал программировать на си++ до того как изучил его, и разбирался по примерам и говноучебникам вида: «выучи си++ за 21 день», с примерами для шестой студии. И я далеко не сразу смог разделить у себя в голове си, си++ и вин-апи, так как подавалось все скопом. Уже с годами знания выкристализовались, разложились, да и качество читаемой литературы выросло. Так вот я уверен что было бы лучше учить языки последовательно, не смешивая из в эдакий дикий коктейль.
UFO just landed and posted this here
Я вообще в восторге от того, как он «доказал» пригодность плюсов для простых задач, написав программу для поиска регекспом ссылок на страничке длиной в 60 строк (!), несмотря на использование последнего стандарта и буста. Ручная сброка GET-запроса и парсинг ответа прилагается.
Задача действительно простая, 60 строк — немного. Что не так?
То, что на языке, имеющем полноценную стандартную библиотеку, этот код займёт 3 строки (ну, плюс ещё строк пять, если язык исповедует «труЪ ООП»).
Даже если мы создадим язык, в котором операция «получить файл, пройтись регэкспом и выдать массив» будет встроенной, т.е. реализация займет одну строку, это ничего не докажет. Это специфическая задача и ничего не показывает об универсальном языке программирования, под специфическую задачу не заточенном.

Это — не стандартная задача.
Работа с HTTP — стандартная задача. Если в коде приложения вручную собираются HTTP-запросы — это ненормально.
Настолько ли стандартная, чтобы быть в стандартной библиотеке?

Да, функция вида «получить файл по адресу в строку» наверняка где-то реализована и вызывается тоже в одну строчку. При помощи той же WinHTTP если речь о Win32, реализуется просто. То, что автор не стал искать такую библиотеку — другой вопрос. Это вопрос «поколений» — возможно, он хотел сказать, что, мол, даже такая сложная (по его мнению) задача как вот эта реализуется так просто. Считать работу с HTTP тривиальной, простой или сложной задачей можно по-разному, в зависимости от основной сферы деятельности. Если, например, кто-то в основном занимается разработкой под микроконтроллеры, и для него работа с HTTP — ручная, сложная вещь, то демонстрация С. будет восприниматься именно как «ого, действительно просто». Например, просто за счет использования класса строк вместо работы со строками в С стиле.
К вопросу о стандартности HTTP и включению в стандартную библиотеку. Запилил вопрос на CodeGolf.StackExchange:

Debunking Stroustrup's debunking of the myth “C++ is for large, complicated, programs only”

Сейчас там будет полный список языков, у которых в стандартной библиотеке есть HTTP. С примерами кода. :)
Если не ограничиваться стандартной библиотекой, то вскрывается еще один минус С++ — подключение внешней библиотеки не всегда просто. Просто подключаются только header only библиотеки шаблонов, при условии, что ваш компилятор эти шаблоны переварит. Хорошо, если вы найдете готовые бинарники, подходящие вам. Часто приходится собирать все самому и тут может оказаться, что библиотека просто не собирается вашим компилятором и надо либо искать что-то другое, либо модифицировать код библиотеки.
На самом деле не совсем так. На линуксе есть пакетные менеджеры, если библиотека есть в репозитории все ок.

Если нет, можно сделать make install.

Если библиотека использует ту же систему сборки, что и ваш проект ее можно тривиально включить в сборку (актуально как минимум для CMake и autotools).

Если библиотека вообще не собирается на вашей архитектуре/версии компилятора, то это либо плохая библиотека, либо повод сделать патч :)
Линукс — не единственная система, под которую пишут код на С++. Не везде есть пакетные менеджеры.
Ок, я в последнее время больше связан с линуксами и маками, поэтому пишу про то, что знаю.

В самом деле еще остались системы без пакетных менеджеров? Я слышал для винды что-то в этом плане делалось. Плюс пакетным менеджером возможности не ограничиваются (ссылка на стандартные системы сборки).
Делалось, появилось в Windows 10, но пока вроде только для программ. И то пока не для всех. И то не помню, с удалением или без.
NuGet уже давно поддерживает C++.
Насколько я понимаю, CMake нормально переваривает любую систему сборки. Во всяком случае, в neovim (единственный проект, который я знаю, который не считает, что зависимости должны устанавливаться пакетным менеджером) как‐то с этим нормально справляются.

make install делать не рекомендуется, если только вы ставите не в каталог, который потом будете подключать через LD_LIBRARY_PATH и который содержит либо только одну конкретную зависимость, либо только зависимости для одного конкретного проекта (соответственно, в обоих случаях его можно снести, зная, что именно при этом поломается и что именно вы сносите) — make uninstall далеко не всегда есть. Тот же CMake не генерирует его по‐умолчанию.
Отлично, посмотрим, сколько языков из более-менее современных (эпоха http) имеют в стандартной библиотеке работу с http. И сколько таких языков вообще, а потом посмотрим долю.
В итоге получается неравноценное соревнование: соревнуются языки, которые поддерживают работу с HTTP с C++ в целом, серьёзно? А то, что на C++ можно «эмулировать» работу любого языка, который есть в том списке — не берётся в счёт?
А теперь ответы:

Python 2: где обработка ошибок? А в остальном — да — отличная работа с HTTP.
C#: угумс, но сначала поставим .NET для Windows и что-то ещё для других платформ, где, по рассказам, реализация ещё глючная (я не говорю, что для C++ ничего не надо ставить — просто C++ это проще).
UNIX shell: оо, прям кроссплатформенное решение, вместе с использованием кроссплатформенных утилит lynx и grep. С таким же успехом на C++ можно написать утилиту show_straustrups_lonks и в одну строчку выполнить её.
PHP 5: очень смешно наблюдать, как язык который заточен под работу с web-технологиями сравнивается с С++ в возможности закачивать файлы. Но ладно, сначала поставим какой-нибудь веб-сервер, который, скорее всего, написан на С++ — где можно будет запустить скрипт (правильно я понимаю, как работает PHP ?)
Scala: нельзя придраться — функциональное программирование и всё такое. Разве что C++ поддерживает, кроме всего прочего, и функциональное программирование.
Node.js: то же самое, что и PHP — нет смысла соревноваться
Haskell: снова функциональное программирование сравнивается с императивным. Да, и ещё Haskell популярный (извините заранее, никого не хочу задеть)
CJam: «CJam does not have regex»… «Try it using the Java interpreter like java -jar cjam-0.6.2.jar file.cjam»… — Очень удобно

Просто хочу сказать, что каждый язык имеет свою нишу. И что-то, что в одном языке делается просто, то в другом — это делается или монструозно, или вообще не делается (можно ли с javascript вызвать системную функцию, например ?)
можно ли с javascript вызвать системную функцию, например
легко
Вот здесь написано:
JavaScript does not have any facilities to interact with the OS

А здесь:
JavaScript runs in a sand-box, meaning that it cannot interfere with the user's computer

А с помощью Child Process можно запустить дочерний процесс.
Я не знаю JS, но, для общего развития, как вызвать CreateProcess(), например?
А разве JS нужен для того чтобы вызывать системные вызовы? Если Вы в своем проекте что-то подобное пытаетесь делать, то Вы видимо не выспались!
Нет. Вы читали комментарии выше? Я сказал «С javascript нельзя вызвать системную функцию» («каждый язык имеет свою нишу» — javascript не для вызова системных функций). Мне в ответ написали — «легко». Я попросил показать на примере
JavaScript это такой-же язык как любой другой. Возможности зависят от среды выполнения — всегда есть внешние функции (которые сами реализованы не на JS) которые можно вызывать из JS. Например — функции для работы с DOM, CSSOM и объектной моделью самого браузера.

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

Node.js — это технология для разработки сервера на JavaScript, там возможности намного шире.

Любопытно кстати, что C++ тоже можно аналогично «кастрировать». У google есть технология NaCl (NativeClient) — выполнение нативного кода в безопасной песочнице в браузере у пользователя, аналогично JS. В первой версии песочница создавалась средствами ОС, а C++ был почти обычный. Это уже потом они сделали компиляцию в промежуточный байткод и другую магию.
Всё зависит где запущен JS, если в браузере то никак, если в NodeJS то пишешь свой модуль на C++ и что хочешь вызывай.
ИМХО JS язык встраиваемый(как например и Lua) куда встроишь там и будет работать, хоть в ядро запихни и железом управляй.
если в NodeJS то пишешь свой модуль на C++ и что хочешь вызывай.

Ну, это уже то же что и «хочешь http в c++ — пиши свой модуль и вызывай», так что несчитово.
В конечном итоге для других языков кто то написал библиотеку для работы с http, и рано или поздно корни этой библиотеки упрутся к какой либо компилируемый язык. Да где то сделали готовую библиотеку для работы с тем же HTTP но как это связано с самим языком?

Для примера, у меня на работе валяется самописный модуль для NodeJS которые позволяет читать/писать память приложения по его PID. Реализация ну строк 100 от силы, причём процентов 70 это инициализация всякая. Есть ещё куча мелких программ на NodeJS для парсинга всяких хитрых бинарных файлов в JSON. Но как это связано с самим JavaScript?
Да где то сделали готовую библиотеку для работы с тем же HTTP но как это связано с самим языком?
Неправильно рассматривать язык отдельно, а библиотеки отдельно.
Это очень удобно, когда вместе с языком ставится стандартная библиотека, которая решает 95% повседневных задач. Как в питоне например.

Давайте проведем эксперимент — посоветуйте мне библиотеку для работы с HTTP в С++?

Я уверен, предложите десяток вариантов. А мне нужен ровно один. И чтобы не было проблем с деплоем.

На всякий случай напомню контекст — Страуструп утверждает, что C++ — разумный выбор, когда требуется написать маленькую одноразовую утилиту («Five Popular Myths about C++; 5. C++ is for large, complicated, programs only»). Так именно на таких задач особенно важна богатая стандартная библиотека.
Неправильно рассматривать язык отдельно, а библиотеки отдельно.
Это очень удобно, когда вместе с языком ставится стандартная библиотека, которая решает 95% повседневных задач. Как в питоне например.

ИМХО язык это грубо говоря синтаксические конструкции его образующие. Библиотеки это ощутимый бонус, и да это очень удобно. Но вот к языку отношения не имеет.

Давайте проведем эксперимент — посоветуйте мне библиотеку для работы с HTTP в С++?
Я уверен, предложите десяток вариантов. А мне нужен ровно один. И чтобы не было проблем с деплоем.

Я не С++ник мне в голову приходит только curl он вроде C но на С++ его подключить не проблема.
На всякий случай напомню контекст обсуждения — Страуструп утверждает, что C++ — разумный выбор, когда требуется написать маленькую одноразовую утилиту

Если ты отлично знаешь С++ и отвратительно Python то разумный выбор будет С++. Всё относительно. И надо с начало понять что есть маленькая одноразовая утилита и для чего, вот мне надо было писать в память чужого приложения, утилита одноразовая и маленькая, и оптимально ложилась в С++. Но я использовал NodeJS + C++
Для C# среда уже предустановлена для свежих виндов, а вот для C++ рантайм надо ставить отдельно.
Спасибо, что подытожили.

Как и ожидалось, в общем: либо специализированные языки (PHP), либо небольшое количество универсальных (Шарп и др).
Ничего такого, что позволяет кидаться фразами вида «в современных языках это делается в 3 строки» как аксиомами.
Python 2: где обработка ошибок?

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

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

C#: угумс, но сначала поставим .NET для Windows

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

UNIX shell: оо, прям кроссплатформенное решение, вместе с использованием кроссплатформенных утилит lynx и grep.

Не нравится lynx — используйте другой вариант с wget. Lynx там ради лулзов.

PHP 5: очень смешно наблюдать, как язык который заточен под работу с web-технологиями сравнивается с С++ в возможности закачивать файлы.

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

веб-сервер, который, скорее всего, написан на С++

C++, первая версия которого написана на C, первая версия которого написана на ASM. Что вы хотели этим сказать-то?

Разве что C++ поддерживает, кроме всего прочего, и функциональное программирование.

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

Да, и ещё Haskell популярный (извините заранее, никого не хочу задеть)

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

можно ли с javascript вызвать системную функцию, например ?

Да. Язык никак это не ограничивает. Возьмите ноду, какую-нибудь реализацию для .NET или любую другую среду исполнения кроме браузера — и дерзайте.
show_straustrups_links

Вообще, несколько языков всем утёрли нос своей стандартной библиотекой. :-D

Wolfram:
Import["http://www.stroustrup.com/C++.html", "Hyperlinks"]

PowerShell:
(iwr "http://www.stroustrup.com/C++.html").Links | %{ $_.href }
Вы полностью правы. Посыпаю голову пеплом. Может меня не правильно поняли, но я хотел сказать, что не нужно смотреть на язык в целом, смотря лишь на то, поддерживает ли стандартная библиотека работу с HTTP или нет. И да, я полностью согласен, что наличие такой библиотеки упростило бы жизнь C++-программиста. Но тогда бы уж хотелось и полноценную работу с файловой системой, возможность работы с теми же форматами (JSON, мейнстрим сейчас)… ну и каждый может добавить свою хотелку. Но, снова же, если говорить о том, что на С++ можно писать маленькие утилитки-программки, то да — можно, но нет — лучше поискать альтернативу — тот же питон или bash.
Отдельное спасибо за вопрос на CodeGolf.StackExchange.
Но ладно, сначала поставим какой-нибудь веб-сервер, который, скорее всего, написан на С++ — где можно будет запустить скрипт (правильно я понимаю, как работает PHP ?)
Нет. Веб сервер — приложение, которое постоянно слушает какой-то порт (обычно :80) в ожидании http запросов, и на основе этих запросов решает какой именно скрипт вызывать, и нужно ли его вообще вызывать, или же достаточно выдать в сеть картиночку с котиком или статический html файл. Плюс всякие полезные штуки типа кеширования. Это не только PHP касается, но вообще всех «веб»-языков.

А сам PHP можно запускать из консоли (шеллскрипта/батника), или даже скомпилировать(!) в исполняемый файл.
Может это и ТИПОВАЯ задача, но я был бы сильно против, чтобы такие инструменты были в стандартной библиотеке языка.
Ну и потом, Бьёрн иллюстрирует API конкретной библиотеки, asio — на Qt, мне кажется, я бы написал в два раза короче.
Qt ( по крайней мере в версиях 3 и 4 ) не очень-то то здорово работал с сетью. То есть для обычный гуи программы вполне приемлемо, но не эталонно хорошо.
Больше всего меня бесило что создание объекта QSocket не создавало системный сокет. Сокет создавался лишь при вызове connect(). Такое вот улучшение, которое убивало прозрачность и предсказуемость кода.
Я сперва написал реализацию канала tcp под posix сокеты, а потом портировал под винду используя Qt. И мне почему-то не казалось нелогичным создание сокета только при коннекте. Более того, я считаю setSocketDescriptor очень неплохой штукой.
Вообще изначальная ветка была про «многословность», так что оставим это =)
Hа Borland Builder C++ это таки занимает одну строчку.

Но потом работа таких програмистов сводится к поиску — где мне найти компонент бухгалтерия.
Я не понимаю всей этой паники по поводу обучения программированию новичков.

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

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

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

Но если этого _не_ делать, то потом возникают реальные обсуждения в стиле «печатной машинки Киллиана».

www.gazeta.ru/comments/2014/12/22_e_6355209.shtml
Я с Вами частично соглашусь, хотя бы потому что я как раз прошел это на своей шкуре. Начал изучать в 9 классе С++, долго матерился и бился упорно головой, писал в Си-стиле, не читал книжек, набивал шишки.
В итоге когда через год стал смотреть на Delphi, Javascript а через пару лет еще и PHP, то многие внутренние особенности этих языков уже не вызывали вопросов =)

с в) не соглашусь.
в С++ синтаксический сахар в виде шаблонов дается зачастую бесплатно. На хабре была статья ( увы нет в закладках), как человек на шаблонах под микроконтроллеры генерировал код, причем результирующий ASM был такой же оптимальный, как человек бы вручную соптимизировал.
inline template<> имеет такой же overhead, как и макрос, по сути.
Есть мнение, что нам просто не хватает достаточно строго разделение между, назовём так, «архитекторами» и «кодерами». Задача первых — собрать сложную систему из имеющихся, а порой и не имеющихся частей. Задача вторых — выполнить задание с бумажки. И этих людей обучать нужно по-разному.

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

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

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

Конечно, никто не ограничен одной специализацией, но способ обучения будет уже другой. Сам я взялся сначала за си, потом и за C++ курсе на пятом обучения. Задачи были и раньше, но я делал только учебный план. На тот момент я уже был способен делать много чего как веб-программист. Последний раз я программировал делал что-то для веба (не на C++ :)) года 4 назад, недавно попытался понять AngularJS, за полдня заработал вывих мозга и отложил это дело. Не жалею, что начинал с JS и PHP, но, похоже, уже никогда к ним не вернусь. Специализация должна определять метод обучения, а не картинка «хорошие программисты получаются так».
Мне кажется, что обучение программированию надо начинать, как ни странно, с программирования, а не с технологий и языков. Мы в свое время начинали с паскаля, который именно для обучения и был создан, это потом на него накрутили объекты и Delphi. Сначала на простом языке человек учится составлять вообще алгоритм, понимая принципы работы компьютера, разбирается с примитивными структурами данных. Этот курс, помню, занял год в школе, но это же арифметика, без которой не будет ни системного программиста, ни архитектора, ни кодера. И современные скриптовые языки, мне кажется, не очень подходят, потому что в них уже все это реализовано, и человек начинает мыслить примитивами языка, а не алгоритмами.

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

А как человек решит, что он системщик или архитектор? Мне кажется, что базовый курс алгоритмов надо выдавать в школе, как и алгебру, а к универу человек уже сможет достаточно попробовать, чтобы знать, что ему интересно. И в универе да, там уже системщики получают ASM/С/С++, а прикладные программисты могут писать вообще на чем угодно.

Хотя опять же, системщик системщиком, а я хоть и пишу в основной работе на С++, тем не менее делаю сторонние хобби-проекты на PHP/JavaScript/Python, что позволяет увидеть новые подходы, которые часто чудесно переносятся в основную работу. А пару лет назад стенфордская книжка по фукциональному программированию не сделала из меня функциональщика, но открыла глаза на то, что лямбда функции — они не только для короткой записи кастомного компаратора в std::sort(). Поэтому универ должен давать обзорные курсы разных языков и парадигм.
Основы нужны всем, это очевидный и объективный факт. Но возникает всё та же проблема, что именно должно входить в основы. Очевидно, алгоритмы, структуры данных, базовые понятия о парадигмах.Что ещё?

Это та же проблема, что и с математикой. Где заканчиваются основы и начинается специализация? Производные и интегралы это основы? Пределы? Ряды? Мне повезло, в универ я пришёл из математического лицея, всё это я и так знал. А поступившие из школы не знали. Под конец обучения были те, кто без лицейской подготовки понимал непрерывную математику намного лучше. В общем, в ходе обучения границы основополагающих понятий имеют мало значения, если человек уже способен понять, что ему нужно, а что — нет. С помощью преподавателей или хороших книжек, конечно. В таком случае, основы должны быть минимальны. Шерлок не зря говорил, что «разум — это чердак». Всё туда не влезет.

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

Что касается языка для основ, тут можно обсуждать бесконечно. Паскаль хорош для обучения императивному подходу, классика. Но после этой классики у нас только 3 из 50 въехали в функциональное и логическое программирование без особых проблем, у остальных были крайние непонятки. Для всех троих паскаль не был первым языком. Основы действтильно надо давать, начиная не с технологий и языков. Начинающим было бы намного проще понимать, если бы им показывали не «как делать это на Паскале/C++/JS» а всю концепцию сразу. Взять сразу и JS, и паскаль, и, например, Haskell. После чего объяснять основы с примерами сразу на всех трёх. Чтобы не привязывались к примитивам языка и учились понимать структуру, а не слова из кода, смолоду.
>Но после этой классики у нас только 3 из 50 въехали в функциональное и логическое программирование без особых проблем, у остальных были крайние непонятки. Для всех троих паскаль не был первым языком

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

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

У нас в универе курсы математики были очень интересно построены. Итак, у нас есть база в виде алгебры, на которую навешивается матан и линейная алгебра. Матан в какой-то момент становится комплексным на полях, иными словами, происходит обобщение, и все теореты 1-го курса на 2-м рассматриваются с новой точки зрения. Матричным операции обобщаются тензорнам анализом, а потом вся математика внезапно оборачивается функциональным анализом операций, который еще раз обобщает все, что было до этого в одну теорию более высогоко порядка, еще раз повторяя все теоремы, только опять же, в новом свете. Параллельно проходит куча специальных курсов, уже использующих готовые на тот момент знания.

А теперь обратно к программированию. Любой школьник способен понять процедурное программирование + структуры данных. Классы — это обобщение процедур-данных. Объекты — обобщение понятия интерфейс. А функциональное программирование — это дополнительное обобщение. Упомянутая мной книжка из Стенфорда была устроена именно так: выстраивала иерархию обобщений. Ни одна документация по лямбда функциям ни в одном языке не содержала этой иерархии, именно поэтому научиться мыслить на новом уровне абстракции по ним невозможно. Если ваш университетский курс программирования и CS не был цепочкой вот таких иерархий, то меня абсолютно не удивляет, что только 3 из 50 людей въехали в теории более высоких уровней.

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

Предположим, нам нужны хорошие интерфейсы. Для этого мы, как правило, берём дизайнера и программиста. К программисту выставляем требования на знание технологий, используемых в проекте для создания интерфейсов, пусть это будет игровой проект на cocos2d-x с C++ в качестве основного языка. Если представить идеального кандидата, то получится, что для него совсем не обязательны фундаментальные знания программирования.

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

Я всё это говорю всё к тому же. Мне кажется, мы слишком высоко задрали планку «программиста», и стоит поделить некоторые вещи, а кое-что и вовсе вынести из областей, традиционно считающихся «программистскими». По моему опыту, многие учёные (в смысле, научные сотрудники), могут написать простенькую программу, облегчающую им жизнь и вычисления. Старики на фортране, молодые уже и на JS. Они же не относят себя к программистам. Для использования таких штуковин, как cocos2d-x даже не нужно особого понимания языка, только базовой концепции и инструмента. Это, условно говоря, эдакие ПТУшные специальности. Но поскольку ПТУ как класс учебных заведений для ИТ не существуют, иметь дело с этим нужно ВУЗам.

У нас критическая нехватка кадров, а мы обсуждаем, как нам сделать идеальных программистов. Да не нужны они! Нужно решать вполне конкретные задачи. Из того гибрида мамонта с инфузорией, что выпускает большинство ВУЗов в РФ не сделать ничего. Для чисто прикладных задач они считают себя слишком крутыми, для архитекторских невероятно слабы. Есть крутые самоучки, на них ведётся охота с высокими ставками. Небольшим компаниям приходится выжимать все соки из пары гениев и молиться, чтобы те не окочурились. Не думаю, что в более «цивилизованных» странах ситуация сильно лучше. Да вы посмотрите на дырявый софт, предлагаемый «стартапами». Там площадь дыр больше, чем живого места. И это не от «продуктоориентированности», а от банальной нехватки прикладных специалистов. По интерфейсу, по сетевому взаимодействию, по базам данных… А из университетов выходят псевдоуниверсальные псевдопрограммисты, как бы знающие почти всё. Только применять не умеющие. От того следуют «трендам» не задумываясь. BigData, NoSQL, чего там ещё было за последнее время. BigData в 95% — неумение правильно структурировать. В NoSQL тоже нужно понимать задачу того или иного типа хранилища. Нужно использовать сильно связные данные — берём реляционную базу, не даром же так названа. Поименованые, но дьявольски разнородные — ключ-значение. Это можно объяснить за 2 года в ПТУ, но почему-то за 5 лет в ВУЗе — нельзя. А люди обсуждают, какой язык лучше или хуже для первого. Да не в языке дело! И король голый! На 5 человек, решающих задачи, нужен только один, досканально понимающий все эти задачи и систему в целом. И по какой-то причине у нас пытаются готовить только этого одного, но не остальных пять.

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

Я за то, чтобы основы императивного подхода преподавали в школе. А дальше — веер возможностей и специализаций, выбирай не хочу. Проблема же наших ВУЗов не в широте мировоззрения (которое на самом деле необходимо, иначе уменьшается обучаемость и потенциальные способности), а в отсутствии практики. Можно сколько угодно рисовать диаграммы данных, но если не спроектировать реальный веб-магазин на курсовик, то грош цена знаниям и ноль умений. Если не преподавать курс основ безопасности — с реальной демонстрацией уязвимостей и путей решения проблем — то получите дыру вместо сайта.

Я не понимаю, почему у нас не в почете трехлетнее бакалаврское образование. Его более чем хватает, чтобы создать узкого специалиста, который будет способен написать по проекту компонент системы. Выдали основы, выдали инструмент, выдали теоретическую базу под инструмент — вот и готовый спец. Я не уверен, что для этого хватит ПТУ, ведь даже для самой простой задачи необходимы инженерные навыки. Иначе «узкие специалисты» ПТУ-шники будут писать в индийском стиле, и попробуй их потом переучить. Могу предположить, что у вашей девушки-дизайнера все таки есть высшее образование, и для нее учиться — это нормальный процесс.

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

Это нормально — подоходов много, императивное используется повсюду, почему бы не начать изучение с него (это наиболее соответствует естественному восприятию алгоритма как набора шагов), а потом перейти к Object Pascal и ООП?

Но после этой классики у нас только 3 из 50 въехали в функциональное и логическое программирование без особых проблем, у остальных были крайние непонятки

Потому что что функциональное, что логическое программирование неестественны.
Мы живем во вселенной, где время движется в одном направлении. Сначала я беру ручку, потом снимаю колпачок, потом пишу. Сначала я объявляю переменную, потом ее использую.
А в логическом, мин пардон, или функциональном, нет «времени», это неестественный для человека метод. Так что ничего удивительного в том, что понимать эти 2 принципа тяжело.
Зная достаточно С++, вам будет легко выучить С. Изучая С перед С++ вы столкнётесь со множеством ошибок, которых легко избежать в С++, и вы будете тратить время на изучение того, как их избежать.


Ну так в этом и есть суть обучения. Если ты умеешь работать со string, но при этом не понимаешь как строка представлена в *char, то наверное тебе работать будет не очень удобно. Большая часть задач именно по изучению С так и построены, чтобы разобрать моменты, которые надо понять, чтобы двигаться дальше.

Порядок изучения должен быть таким:
Assembler->C->C++->С#/Java->Методы программирования (Алгоритмика, MPI)/ Операционные системы (Kernel Drivers) -> Теория информации (Разработка в соответствии со стандартами проектирования)
Ваша цепочка крута, конечно… но есть ещё куда двигаться влево и вправо. :) Вообще, каждый должен выбирать, какой уровень абстракций его интересует, и сконцентрироваться на нём, заглядывая влево-вправо по мере необходимости. Весь диапазон всё равно не охватишь.
Порядок изучения должен быть таким:

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

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

Лично мне тоже нравится идея обучения, разматывающая весьма непростые вещи от условной середины, по спирали, вверх, вниз и в стороны:) Тут изучают атомы и элементарные частицы, а здесь — планеты и галактики. Средняя школа и первые курсы ВУЗа должны сориентировать в цифровой вселенной, а дальше — смотря чего больше хочется в жизни: шестнадцатиричных кодов или паттернов проектирования…
Я когда-то начинал с C++, потом была джава, а потом и питон присоединился… Так вот я бы предпочёл чтобы всё было наоборот или хотя бы начать с джавы. Тонны ньюансов не нужны на старте. Нужно уметь программировать, а не знать, как устроена строка. вот программировать начинать гораздо приятнее на более высокоуровневых языках. А в ньюансы вдаваться по мере необходимости.
Пожалуй С++ после паскаля отбило у меня желание программировать на долгое время и предопределило уход в сторону от программирования в сис админы. Сейчас периодически пишу какие-то вещи для автоматизации на питоне и вполне себе доволен.
Почему asm первый? Может лучше сразу с машинных кодов начинать?

Мне кажется, что надо в самое начало ставить курс алгоритмов/данных, потом С++/Java/C#, а потом уже asm (илм параллельно с С++) и потом уже ОС и теории. Фишка в том, что первый курс можно читать в школе для ознакомления с программированием вообще, а вот asm я бы в школе давать не стал, единицы поймут.
Почему asm первый? Может лучше сразу с машинных кодов начинать?
С теории цепей и схемотехники.
Кстати говоря, у меня в институте так и было =) АСВТ было параллельно с asm.
квантовая механика->материаловедение.

А то не все понимают как происходят квантовые процессы в транзисторах.
Я еше ремонтировал отдельные ячейки ОЗУ в Наири-2
Может лучше сразу с машинных кодов начинать?

У меня именно так.

Мнемокоды калькулятора МК-61 -> паралельно в школе basic (казавшийся чудовищно примитивным) -> университет С++/Asm -> далее Delphi (для прикладных задач, тоже казался примитивным по сравнению с плюсами) -> C# и опять С++, уже обновленный
У нас в школе были калькуляторы с мнемокодами, но уже тогда я знал паскаль и имел представление про asm, поэтому калькуляторы казались чем-то излишним.

Интересно, чем вам примитивным казался Object Pascal? Я помню, меня приводило в полный восторг, как Borland удалось сделать из довольно неуклюжей объектной модели TP весьма изящную на то время VCL, по образу и подобию которой потом проектировали .NET. С++ конечно дает более легкие средства контроля над выполнением кода, но в плане создания интерфейсов он все же попроще.
OP казался примитивным из-за отсутствия (тогда) шаблонов и обобщений (generic).
Хотя рисовать Win программы было очень легко и удобно.
Асм это мнемоническое представление машинных кодов. Разница лишь в удобстве написания и чтения.
Когда я начинал кодить, я делал это в маш.кодах, т.к. ассемблера не было.
Это фатальная разница, тем не менее.
И, наконец, какая из версий compose() более эффективная? С++ — потому что ей не надо подсчитывать символы в аргументах и она не использует динамическую память для коротких строк.
Однако Великий слегка гонит — хотя оптимизация аллокаций для коротких строк за счет встроенного в std::string буфера возможна, никто не гарантирует что так и будет. Например в libstdc++ и libc++ это не так (стандартная C++ либа на Linux и новая либа от создателей Clang). Если скорость некоторого куска кода весьма важна, приходится разбираться и лезть в кишки.

С точки зрения самого языка все ОК — ничего не мешает написать контейнер с нужными свойствами. Но ожидать что STL прямо так оптимален для всего наивно. Сложно удовлетворить конфликтующие требования, например оптимизация для коротких строк увеличивает размер объекта и на некоторых задачах это может быть нежелательно.
В libc++ SSO есть. В libstdc++ будет наконец в следующей версии (если все пойдет по плану).
UFO just landed and posted this here
А все проблемы отчего? Оттого что индексация не с нуля!
UFO just landed and posted this here
0. Введение
1. Миф 1

i. Миф i

N. Миф N

Индексы — служебная информация, названия — пользовательские строки, поэтому индексация разная.
UFO just landed and posted this here
Ну преподавать СРАЗУ С++ я считаю слишком для юной психики. Миф о том что С++ — это хороший язык чтобы понять основы — не более чем миф.
Начинать надо с простого языка, чтобы преподавать основы алгоритмики: Python для начала хорош, C# если к типам хочется приучать сразу, Pascal старый добрый тоже хорош, но на нём просто уже не пишут.
C++ и Java всё же два языка, до которых надо дорасти, особенно C++. Как правило к языку C++ и идут через язык C, потому что язык C позволяет понять работу с памятью и адресацией, чтобы потом перейти к Assembly, а затем также пойти вверх и выучить ООП и шаблоны языка C++.
И да, инициализация вектора как массива в C++ работает далеко не во всех компиляторах, которые заявляют о поддержке C++11.
Слишком оптимистичная статья в отношении C++. Могу пройти по всем мифам, но в целом всё верно, за исключением тона подачи материала.
Очень сильно зависит от самого обучающегося :) Я в свое время еще в средней школе начал изучать программирование с C++ и до сих пор считаю это правильным подходом.
Java — очень простой язык с очень сложной экосистемой. Я бы как раз начинал учить народ именно Java, только заменив JDK чем-то менее разухабистым. Ну или заставляя студентов реализовывать большинство применяемых классов.
У Страуструпа два достоинства — он сделал язык в свое время и в своем месте, нужный сообществу и безальтернативный в своей нише до сих пор, и не забросил его, как Вирт забрасывал кучу своих языков. Но его статьи и книги… Лучшая книжка Страуструпа — Дизайн и эволюция языка С++. Иными словами «список костылей для С в хронологическом порядке». И С++, по-моему, учить нужно так: Язык С Кернигана и Ричи, затем Дизайн и эволюцию, затем уже книги Саттера или Мейерса для best practices, затем их статьи для С++11. Если ничем другим не заниматься, прочитать эти 3000 страниц можно за неделю. А дальше, зная всю хронологию и где что смотреть, спокойно брать любой учебник по С++ и решать задачки, процент wtf будет минимальным.
А вот книжки чисто по С++ у Страуструпа какие-то странные. Видно, что за образец он взял Кернигана и Ричи, но обучать людей С++ таким образом, как будто всей его истории не было — по-моему заставить человека говорить wtf на каждой странице и ничего не понять в итоге.
Частично wtf снимаются повторным прочтением книги. Сложные технические книги лучше вообще читать дважды (если они интересные при этом, конечно): так из них усвоится почти ровно в 2 раза больше информации, проверено.
Насчёт ругани на Java по поводу отсутствия автоматического управления ресурсами — а чем try-with-resources не угодил? Очень просто, удобно и понятно, сразу видно, где конкретно ресурс будет закрыт. Можно, конечно, забыть его написать, но и в C++ масса способов забыть удалить память/закрыть ресурс.
Насчёт ругани на C по поводу отсутствия сборщика мусора — а чем аллокация на стеке не угодила? Очень просто, удобно и понятно, сразу видно, где конкретно память будет освобождена.
Ну, справедливости ради, из-за инлайнинга это может быть уже не так очевидно, хотя это скорее ошибка компилятора, чем способа. Почитайте о проблемах использования alloca (выделение памяти на стеке).
Я не об alloca, а старом добром выделении структур на стеке (типа `struct Foo foo;`). Штука удобная, но крайне ограниченная — указатель на такую структуру можно передавать только вниз по стеку, причем следя за тем, чтобы нижележащие функции тоже никуда этот указатель не передали. Ну тут все понятно. Да здравствует сборка мусора, где об этом думать не нужно.
Но да здравствует ли? Страуструп говорит, что нет. Память — всего лишь один из видов ресурсов. И try/using является _точным_аналогом_автоматической_памяти_ в мире ресурсов. Он примитивен. Try/using — это чисто ограничение времени жизни ресурса фигурными скобками. Если же время жизни ресурса нужно отвязать от фигурных скобок (например, заныкать в объект со счетчиком ссылок на этот ресурс, завести пул ресурсов и т. п.), начинаются те же самые проблемы, которые есть с парами malloc/free в языке С. На сборщик мусора полагаться при этом нельзя, потому что он только для памяти и вызов финализатора недетерменирован, финализация вообще может никогда не произойти. В итоге и получается, что код управления ресурсами на языке без RAII похож на код на C с ручными free (явный подсчет ссылок на ресурс и вызов финализатора) или же приходится писать суррогатный RAII с батареями try, где ссылки на ресурс будут считаться автоматически.
Не знаток Java, но судя по описанию есть ещё одна проблема, кроме как не забыть везде писать try для подобных объектов. Пусть несколько членов-данных какого-то объекта реализуют этот метод close(), тогда внутри метода close() такого объекта мы должны будем явно вызвать руками все эти методы, тогда как для деструкторов в С++ соответствующий код будет сгенерирован автоматически.
Есть такая особенность, да. Когда вы пишете явно close для своих ресурсов, вы указываете, что являетесь их владельцем, и жизненный цикл ресурса совпадает с жизненным циклом вашего объекта. В плюсах вы должны взамен аккуратно использовать unique_ptr или shared_ptr.

Кстати, в Java неплохо решили проблему выбрасывания исключений из close(). В плюсах, насколько я понимаю, обработать исключительную ситуацию при закрытии ресурса не представляется возможным.
В плюсах вы должны взамен аккуратно использовать unique_ptr или shared_ptr.
Ну уж нет, аналог вашей конструкции в плюсах — это простое создание объекта на стеке, деструктор будет вызван автоматически при выходе из области видимости.
В плюсах, насколько я понимаю, обработать исключительную ситуацию при закрытии ресурса не представляется возможным.
Вы можете бросать исключения из деструкторов, тонкий момент тут только один: если в процессе раскрутки стека при обработке исключения из деструктора разрушаемого объекта бросается ещё одно исключение, то работа программы прекращается (вызывается std::terminate()), что в целом довольно логично. Сделать как в Java невозможно хотя бы по той причине, что C++ не требует, чтобы объекты-исключения наследовали какой-то интерфейс, вы можете бросить всё что угодно, например, обычное число. C другой стороны у нас есть функция проверки не идет ли в данный момент процесс раскрутки стека (std::uncaught_exception()), поэтому с известными ограничениями можно попробовать реализовать подобный механизм самостоятельно.
Sign up to leave a comment.

Articles