Как я однажды сказал - Си это набор макросов для асма, только они настолько замудреные что приходится писать макросы для Си А вообще Си вне конкуренции, не знаю что вы всё тут обсуждаете, это очевидно и доказывать не стоит.
вы не зрите в корень скорость драйвер ФС, например, тесно связан с блочным устройством если его вынести на кольцо 3, тогда чтобы работать с блочным устройством, ему понадобится использовать write()/read(), а это постоянные переключения уровней привилегий + пока write()/read() определят, что окуда надо прочитать/записать и пройдут через много уровней абстракций... вы спрашивали, уверен ли я я уверен и доказательствами заниматься не собираюсь связано с тем, что UNIX принципиалино отличалась от других ОС тем, что ога революционно была написана на С, а не на ассемблере, в отличие от практически всех ОС того времени а так как развитие вычислительной техники того времени не было столь стремительным и вычислительные мощности были слабыми, любая сторонняя генерация кода (тем же С-компилятором), заметно снижала скорость работы ОС (+ отсутствие современной оптимизации выходного кода) как же многозадачность? O_O разные процессы потрут данные друг друга я уже не говорю про MP-системы что касается размера, его можно сократить до 4K да, кроме того, к вопросу о "выделенном" стеке для x86, x86-64 на дне стека лежит структура thread_info, однозначно идентифицирующая процесс для чего? для константого времени идентификации текущего процесса Код (Text): ; находясь в ядре для x86 mov eax, esp and eax, NOT 8191 преемптивность ядра, т. е возможность вытеснения в режиме ядра при этом, замечу, ESP может не указывать на вершину стека ядра (а в 99% процентах так и есть) а теперь представь, 2 процесса используют один и тот же стек в результате вызова функций ESP первого процесса равен ESP0 - OFFSET, где ESP0 - вершина общего стека далее процесс по какой-то причине переходит в состояние ожидания тем временем второй процесс переходит в режим ядра и получает ESP = ESP0 далее в процессе работы он затрет адреса возврата первого процесса и кирдык
rei3er По сравнению с временем, затрачиваемым на собственно ввод-вывод, потери времени на переключение контекста -- мизер. Кроме того, если так уж создатели системы были так озабочены скоростью, то надо было писать исключительно на ассемблере. Вообще-то революцией к тому времени это уже не было. Мультикс была написана раньше и тоже на ЯВУ -- на PL/1, если точнее. Из неё, кстати, Юникс кой-какие идеи позаимствовал. Кстати, Мультикс по той же причие не получила распространения, хотя кой-где использовалась (вроде как в 2000 году вывели из эксплуатации последнюю машину, работавшую под ней). Ну, сейчас, пожалуй, единственная реальная прибавка к оптимизации -- это способность некоторых компиляторов "обозревать" всю программу, а не отдельные процедуры и функции. Что же касается оптимизации циклов, размещения переменных и т.п., то в 1960-е всё это уже было, и нового там не появилось (ну, если не говорить про всякие хитрые команды вроде MMX, SSE и т.п., аналогов которых тогда не было -- во всяком случае, в "нормальных" машинах). Хотя в принципе Вы правы: лучшие современные компиляторы генерируют более качественный год, чем лучшие компиляторы 1960-70-х годов. А причём здесь многозадачность? Речь-то о стеке режима ядра, а в этом режиме работает ядро оси, а не собственно пользовательский процесс. Произошло прерывание -- управление получило ядро и тотчас переключило стек (если он аппаратно не переключается). И всё Каждому процессору -- свой стек, это понятно. Но именно процессору, а не процессу. Каждому процессу -- стек пользовательского режима Это всё я уже вычитал, но всё равно спасибо Тем не менее, подход, имхо, порочный (большой лишний расход памяти + большая лишняя нагрузка на кэш). Это всё так, но возникают два вопроса: а) а нужна ли эта самая "вытесняемость" ядра? б) нельзя ли реализовать то же самое по-другому? Я отвечаю так: а) без этого можно обойтись, хотя в определённых случаях подобная возможность будет полезной; б) да, можно. Кажджому процессу действительно необходимо выделить свой стек, но не более того. Процессы пользовательского режима работают только в пользовательском режиме -- им стек только пользовательского режима. Процессы ядра работают только в режиме ядра -- им отдельные стеки режима ядра. И плюс дополнительный "общеядерный" стек для обработчиков прерываний, которые, как известно, работают вне контекста какого-либо процесса. В результате экономится приличный объём памяти. Кстати, если не секрет, сколько "процессо-потоков" пользовательского режима всегда работает в Линухе? В Винде -- очень много, а как глянуть в линухе -- не знаю. Точнее, знаю, как посмотреть процессы, но каждый же может иметь несколько потоков, а стек должен выделяться каждому потоку -- а вот про это уже не вем... (Что в ядре Линуха процессы и потоки объединены в одно целое, я тоже уже успел прочитать). Можно доказать правильность алгоритма. Можно доказать правильность перевода алгоритма на тот или иной алгоритмический язык. Но чтобы доказать, что это действительно будет правильно работать, надо ещё доказать, что запись на означенном языке корректно переведена в машинный код, а сама машина не содержит ошибок (как иногда случается). Всё это доказать можно, но довольно сложно. vito И что же этим сказано, уважаемый? То, что есть бумажки, коим не очень-то следуют? Или Вы не в курсе, что ядро Линуха не соответствует каким-либо официальным стандартам Си, а использует специфические расширения компилятора GCC, которые поддерживают отнюдь не все другие компиляторы? Или Вы не слышали, что Ада стандартизирована не хуже Си? Не знаю, какой индивидуум доказывает, что дураки создавали и отлаживали Си... Но вот почему для военных разработок предпочитают всё же другие языки? Или просто в армии одни дубы? А я скажу так: не можешь писать на Си -- не программируй вообще. Потому что сам по себе Си отнюдь не представляет сложности, он лишь плохой язык, но отнюдь не гиперсложный (сложнее Паскаля, но навряд ли сложнее Ады). Ну а если мозгов не хватает его освоить -- то программистом ты точно быть не можешь. Простите, что Вы имеете в виду под Дельфи -- компилятор фирмы Борланд или язык Объект Паскаль, который является входным для означенного компилятора? Что же касается клиентских приложений к БД, то их очень даже нередко пишут на Си++ (который с моей точки зрения ещё хуже Си -- такой же ненадёжный, но ещё и лишившийся простоты). Попрошу заметить: я поливаю грязью язык Си, а не людей, пользующихся этим языком. А насчёт некомпетентности -- извольте доказать. В чём конкретно я не прав? Покажите, в чём конкретно язык Си превосходит язык Паскаль. Тогда и можно будет предметно разобраться, насколько далеко простирается моя полнейшая некомпетентность. Попрошу обосновать, что в этой слакой парочке такого уникального, что замены им нет и не предвидится. Вовсе нет. Просто это язык с плохим синтаксисом, допускающим (и даже поощряющим) "извращённое" программирование. Если очень хорошо себя контролировать, код на нём будет немногим хуже по читабельности, чем паскалевский. Однако этому принципу следуют далеко не всегда. Кстати, от того, что Си называют ассемблером, он таковым не становится. Что в нём ассемблерного? Возможность обращения к спецрегистрам процессора есть? Нет. Возможность обращаться к портам ввода-вывода есть? Нет. Возможность тонкой манипуляции стеком имеется? Отсутствует. Возможность управления прерываниями? Тоже нет. Так где ж ассемблер? Самый что ни на есть обычный ЯВУ. И что в ней такого гипермощного, что поднимает её над другими системами? И что, кстати, в ней до сих пор развивается? "Потенциал" -- это слишком абстрактно, я в силу своей полнейшей некомпетентности понять, что Вы имели в виду, не в силах. А вот с этого места попрошу поподробнее. Вы имеете в виду переход на Висту? Что ж, тут ответить легко. Является ли Линукс классическим Юниксом? Насколько понимаю, не очень. Является ли Солярис классическим Юниксом? Ещё в меньшей степени. Является ли QNX классическим Юниксом? Нет, абсолютно не является. Но, тем не менее, всё это "типа юниксы". Так что, пользуясь Вашей логикой, я смело могу утверждать, что Юникс исчерпала свой потенциал, и ей на смену пришли более-менее совместимые с ней на уровне приложений, но по-другому реализованные внутри операционные системы (а Виста как раз более-менее совместима с линейкой NT). Неужто Вы не в курсе? =-O На Си, уважаемый, на Си. Поэтому-то она такая громоздкая, медленная и ненадёжная. Ну, конечно, не только поэтому, но в том числе благодаря выбранному языку. Или Вы скажете, что создатели Вындовса -- сплошь кретины, коим место в доме умалишённых? im1111 Можно попросить сказать поподробнее, в чём именно Си вне конкуренции? По каким критериям Вы это оцениваете?
насколько я знаю, К. Томпсон написал для PDP-7 усеченный вариант операционной системы MULTICS (изначально UNICS), которая позже трансформировалась в UNIX так что можно считать MULTICS прародителем UNIX ядро не работает само по себе любые действия на нулевом кольце производятся в контексте какого-либо процесса (процесс загрузки не в счет) обработчики прерываний не исключение (прерывания в любом случае прерывают выполнение какого-либо процесса) расход памяти не связан со структурой thread_info (по размеру она значительно меньше даже 4K) + такой подход обладает хорошей переносимостью, поскольку стек есть в подавляющем большинстве архитектур в отличие, скажем, от регистров FS, GS, через которые можно идентифицировать текущий (в контексте которого работаем) процесс или вы знаете другие способы? (так, чтобы они работали за константное время (в не зависимости от общего количества активных процессов в системе)) нужна например для реализации блокировок в ядре если блокировка захвачена процессом на относительно длительное время, то самое лучшее решение для другого процесса, который пытается ее захватить - вызвать планировщик для переключения контекста, чтобы дать возможность в это время поработать другому процессу, а не впустую гонять процессор в цикле ожидания освобождения блокировки да в конце концов преемптивность нужна для реализации таких функций как, скажем, pause() как вы ее реализуете таким образом, что концепция общего стека будет работать? о чем и речь как это вне контекста? представьте себе процесс, работающий на 3-ем кольце генерируется прерывание и идет вызов соответствующего обработчика но значение CR3 и других регистов при этом не меняется, т. е сохраняется контекст процесса + как вы уже сами сказали ядерный стек у процесса должен быть, а он также определяет его контекст не вижу где экономия мне кажется, наоборот увеличивается, ведь по вашим же словам стек ядра у процесса есть но в то же время еще нужны страницы для "общеядерного" стека в любой момент времени не более K процессов, где K - количество логических процессоров (логический в плане того, что это может быть HT-ядро, физическое ядро, физический процессор и т. д) в Linux нет понятия потока есть процессы с общими ресурсами для эффективной реализации семантики потоков на основе POSIX (NPTL) ядро было незначительно модифицировано (введение групп потоков, изменение семантики некоторых системных вызовов, введение фьютексов для эффективной синхронизации) вся остальная работа с потоками сосредоточена на пользовательском уровне кстати, чем не похоже на концепции микроядра? простота (я не шучу) скажем так, объединение подмножеств различных частей Linux - есть классический юникс есть POSIX API, которому должны следовать юниксоподобные ОС Linux ему следует естественно, POSIX API - это только лишь подмножество API Linux, но это не мешает программам, которые используют только POSIX API успешно работать в Linux концепции прав, древовидных ФС, файлов-устройств, каналов и пр. сближает его с классическим юниксом
SII можно, но почему-то товарищи, любители паскаля об этом только рассуждают а мне, как извращенцу, такие вещи нравяться - красиво, и вполне, функцианально) яп-язык программирования, а яву я не перевариваю, впрочем, эта нелюбовь идёт от любви к фирме сан) Necromancer13 >>>>Ему интересно всё. А это означает, что реально -- ничего... вот тут человек прав - нужно сделать выбор направлений. сделай для себя список наиболее интересных тебе вопросов, а потом пробей в инете за что бабок плотят больше) ------------ SII а теперь я молча посозерцаю как ты отобьёшься от публики), но твой стиль мне нравится)
А я не знаю, что мне интереснее всего... наверно, системное программирование. но нравится и прикладное, и Perl, и Python, PHP, и С++ знать не помешало бы... и веб-дизайн нравится мне... да и вообще мне приятно работать под ОС Linux, чем бы я не занимался... Но все же больше всего меня привлекает системное программирование... Язык С мне нравится потому, что и сам Линух на нем написан... а вот под Виндой мне приятнее писать на Паскале и АСМе - так привык... А пока я оставлю у себя GNOME, на BlackBox перейду позже
Necromancer13 у тебя еще много времени для определения пробуй все в конце концов найдешь то, что тебе нравится больше
SII Это шутка такая? Нужно смеяться? Но впрочем, стиль мне тоже нравится Только бумажки? Я занимался "военными разработками". Что именно имеется в виду? Языки моделирования? Абсолютно ни в чем. Паскаль гораздо круче. И вообще все языки которые создавались для обучения, как бейсик, паскаль - однозначно лучше С. Это аксиома. Сладкую парочку Без коментариев. А кто его знает. Звезды так встали Ну хорошо хоть так. А если я на Паскале десяток goto вставлю, как насчет читабельности? Поэтому правильно замечено, писать надо корректно C создавался как альтернатива Асму. Писать на Асме было излишне трудоемко. Потребовался язык, в тот момент для написания ОС, который абстрагирует от машинных команд, но тем не менее будет очень близок к машинному коду. Нонсенс конечно Но тем не менее он был решен. С близок к асму тем, что "привязывает кодера" к низкоуровневым материям, оставаясь номинально, языком высокого уровня. Чтобы писать на нем, то для чего он предназначен, ты должен быть системщиком. Никаких абстракций. То что невозможно, или трудоемко сделать на С, пишется на Асме (ну конечно ты добавишь что в Паскале тоже можно делать вставки). С это уникальное явление, которе позволило расширить границы Асма. Синтаксис...Великолепен. Краток, лаконичен, легко читабелен. И тоже уникален. При его создании явно прослеживается АСМ наследие. Ну если прямая, низкоуровневая работа с памятью - это ЯВУ. Мои комплименты.
vito не могу удержаться) не чушь, а компромисс между чистым асмом и япом) в том же масме можно высокоуровневые команды юзать, что нарушает чистоту асма. а здесь сарказм==100% - доводы==0%)
vito ну, не может яп расширить границы асма) сделать код переносимым - да, ускорить разработку - да) красота определяется психологией чел-а, так что подобные доква - чистой воды субЪектив) вот это, конечно, перл) - тоже аплодирую)
Человеку который хорошо знает Паскаль и не очень хорошо С, всегда будет казаться, что исходники на Паскале читаются лучше чем на С. И наоборот. ИМХО
начали с Windows vs Unix перешли к Pascal vs C ох и любят же тут халивары... осталось только поднять топик Communism vs Democracy (надеюсь, правильно написал все эти страшные слова)
pas ага. а человеку, который знает только Бейсик, исходники на Сях будут вообще не читабельны. Но это вопрос о компетентности. Сейчас обсуждаем несколько иное. Если человек хорошо знает и Си и Паскаль, то легче читаются Си, т.к. не перегружены всякими "begin-end"-ами, "then" и прочим Хотя, как тут кто-то сказал - это субъективное мнение... Когда я с Делфи перешел на Си, писать код стало значительно удобнее. Просто в плане разработки... Си более читабельный.
имхо, нет Pascal объективно более легко читаем другое дело сила привычки когда субъективные ощущения превалируют над объективной стороной вопроса да, на С выражать свои мысли проще засчет отсутствия "засоряющих" конструкций но вот зачастую мысль бывает довольно извращенной, а т. к язык извращенность не запрещает, то в итоге код становится менее понятным
rei3er От того, что прерывание возникает во время работы какого-то процесса, это прерывание не становится относящимся к данному процессу. Процессы -- они сами по себе, прерывания -- сами по себе. Так что выделять стек режима ядра каждому процессу вовсе не требуется в обязательном порядке. Конечно, это будет навязано архитектурой ИА-32, если применять заложенную в неё аппаратную многозадачность (как это реалзиовано в Линух, пока не знаю). Но лично я бы и на ИА-32 использовал единственный TSS на все случаи жизни, а значит, и стек ядра у меня был бы один. Слишком уж неудобна аппаратная многозадачность... Что упомянутая структура маленькая, я в курсе, и в расход памяти её не включаю в данном случае вообще, тем более что он неизбежен, если не менять кардинальным образом форматы управляющих блоков, а значит, не переписывать половину ядра. Но лично мне кажется, что надо получать адрес thread_info (а из неё -- блока управления процессо-потоком, как я его для себя обозвал) не путём маскирования 13 младших разрядов текущего ESP, а просто загружая его из фиксированной ячейки памяти -- в ней хранить указатель на thread_info текущего активного потока на данном процессоре. В итоге -- одна инструкция вместо двух, скорость может быть как больше, так и меньше (в зависимости от попадания в кэш, причём скорее меньше: обращение к ней будет происходить достаточно часто, а значит, и в кэше будет лежать практически постоянно), от числа потоков в системе никак не зависит по понятным причинам. Стек действительно есть почти везде, поэтому и подход будет весьма и весьма переносимым, хотя вариант с прямым чтением нужного указателя из памяти ещё более переносим Однако, сдаётся мне, что погоня за переносимостью приводит к тому, что ОС становится примерно одинаково неэффективной на любой платформе. На современных компьютерах это не очень заметно: процессоры быстрые, объёмы памяти большие, да и сравнивать, в сущности, не с чем (Винда тот же подход исповедует -- просто, в отличие от Линуха, попытка создать переносимую ось мелкомягким не удалась, хотя изначально была, как, думаю, Вам хорошо известно). Видите, мы подходим к "концепции" В ней-то всё и дело. В Линухе, как понимаю, принята концепция, дозволяющая значительной части кода ядра на длительное время переходить в ожидание чего-то там, причём делать это с минимальными ограничениями. В этом случае действительно не избежать введения потоков ядра со своими собственными стеками. Другим способом является жёсткое ограничение возможностей по ожиданию: код ядра может ожидать, но строго определённых вещей, причём переход переходом в ожидание он должен удовлетворять определённым строгим правилам (в частности, иметь пустой стек). В этом случае ожидание реализуется весьма просто с помощью очередей ожидания, но, понятное дело, проектировать и программировать такую систему будет сложнее. Наконец, средний подход, о котором я уже говорил. Потоки ядра есть, и именно они могут ожидать без особых ограничений, имея собственные стеки. Однако всё остальное ядро работает с общим стеком и ожидать не может. Если для обработки чего-то там требуется длительное время или может возникнуть нужда в ожидании, такая обработка передаётся потоку. Если же обработку можно выполнить сразу -- выполняем сразу. В результате нет нужды выделять стек режима ядра каждому процессу в системе -- этот стек становится необходимым лишь потокам, реально работающим в режиме ядра. А так. Я говорил про стек для потоков, работающих в режиме ядра, а не для обычных пользовательских -- последним он не нужен. Происходит прерывание, минимум информации сохраняется в кастрированном стеке, после чего программно происходит переключение на общий стек системы достаточно большого объёма -- это если использовать многозадачность на основе TSS. А если её не использовать (имеется только один TSS), тогда никаких ручных действий не потребуется: любое прерывание переключит процессор на единственный стек режима ядра. И прерывание работает не в контексте прерванного потока, а в своём собственном, потому что оно не привязано к конкретному потоку. Например, завершилась операция ввода-вывода, в связи с чем был выдан запрос на прерывание. Причём здесь тот поток, который занимал процессор во время возникновения прерывания? Да, контекст этого потока надо сохранить, но это единственная "связь" прерывания с контекстом потока. Прерывание совершенно не зависит от того, кого именно оно прервало. Вы либо не поняли, либо невнимательно меня читали. Ещё раз: стек режима ядра есть только у потоков, которые работают в режиме ядра (собственных потоков ядра). Потоки, работающие в режиме пользователя (а их большинство) не имеют стека режима ядра. Вот вам и экономия. Например, в настоящий момент у меня в Винде имеется 517 потоков, из коих почти все -- потоки пользовательского режима. Если каждому выделить по 8 К стека режима ядра, вот уже получаем 4 Мб, ушедших на ненужные стеки. Я бы обошёлся одним-единственным стеком, причём, вероятно, меньшего объёма (в пределах 2 Кб). Естественно, и система была бы по-другому спроектирована. Неверно. Меня не интересует, сколько процессоров физически выполняется, а сколько их присутствует в системе (занимает процессор, находится в готовности к выполнению, находится в состоянии ожидания). Это вопрос терминологии. Лично мне больше нравится принятая в Винде: более чётко мухи от котлет отделяются. Поток -- то, что выполняется (код, стек, содержимое регистров). Но всегда можно о них договориться. Угу, некоторые Винду объявляют микроядерной -- наверное, потому что между программами и истинным ядром имеется более-менее толстая прослойка подсистемы Вин32. В общем, ничего общего с микроядром, обе -- типичнейшие монолиты. Если б приписку не сделали насчёт того, что не шутите, ни за что б не понял. Серьёзно. Это линух-то простая? Только не сравнивайте с Виндой -- я нигде не утверждал, что это хорошая система Хотя, кажется мне, что сейчас и сравнивать-то не с чем: мощное железо развращает, вот и имеем сплошных монстров... В таком случае любую систему, реализующую POSIX API, можно назвать классическим юниксом. Например, Винду, если её подсистему POSIX реализовать в полном соответствии с упомянутым стандартом. Но ведь в последнем случае никто не станет говорить, что Винда -- это Юникс, не так ли? Так что и Линух -- это уже не совсем Юних, а QNX -- абсолютно не Юних. UbIvItS А Вы посмотрите на этот вопрос с другой стороны: многие ли товарищи -- любители Си написали действительно рабочих осей? BSD отпадает -- изначально написана организацией, открытые ныне Солярис и QNX -- тоже отпадают, и по той же причине. Фактически из написанных на энтузазизьме имеем одну Линух. Немного-с, немного-с -- особенно учитывая численность любителей Си А вообще утверждения вроде этого Вашего переводят разговор из одной плоскости в другую: я говорю о технических возможностях языка (и тут Вы соглашаетесь со мной, что на Паскале тоже можно написать ось), а Вы переводите, если угодно, в социальную плоскость (спрашиваете, а почему же, собственно, на Си что-то написали, а на Паскале -- нет). Ну, хоть один честно признал, что он извращенец )) Нет, спору нет, выглядит красиво, но вот разобраться в этом... Даже автору зачастую бывает проблематично, а что говорить о постороннем человеке? Кстати, а что Вы понимаете под "функциональностью" в данном случае? ЯВУ -- это не Жаба имени означенной фирмы, а Язык Высокого Уровня. ЯП в данном случае не является полным эквивалентом: асм тоже ЯП, но не ЯВУ. О чём, собственно, я и говорю. Ну, что наСИльники попытаются меня изнаСИловать, я не сомневаюсь Впрочем, пока лишь с rei3er получается разговор на техническом уровне (что и как сделано, что и как можно сделать, что эффективнее), а не разборки, что круче... vito А вот с Вами, к сожалению, пока что "технический" диалог не очень получается... Посмотрим, что будет дальше. А ну, скажите-ка, какой компилятор точно соответствует стандарту и не допускает от него ни малейших отклонений ни в большую, ни в меньшую сторону? Мне таковых неизвестно; впрочем, я сталкивался лишь с тремя компиляторами: мелкомягким, интеловским и ГНУсным -- и все три имеют расширения, не входящие в стандарт. Это, конечно, не означает, что я против стандартов, но вот бить себя пяткой в грудь, крича, что я-де работаю на стандартном средстве -- извините, нелепо. Если, конечно, лично Вы сами строго не следуете этим стандартам. Линух им не следует. Кстати, вы проигнорировали мой вопрос про Аду Я отнюдь не фанат Паскаля, если уж меня записывать в фанаты -- то я фанат паскалеподобных языков, к коим относится и означенная Ада. Нет, языки программирования для бортовых систем. Или Вы не в курсе, что Пентагон Аду специально разрабатывал для собственных нужд? К сожалению, проблематично создать статистику, какие языки используются в военных разработках и насколько часто -- эту информацию публикуют далеко не всегда. Но вот, например, проскальзывали сведения, что "европейском" истребителе EF2000 "Тайфун" ПО создавалось на Аде, а на шведском "Грипене" -- на Паскале (естественно, не от фирмы Борланд). Почему ж здесь не следуют мэйнстриму и не пишут на Си/Си++? Ну или на Жабе? Вот-вот. Ваши аргументы, прошу прощения, напоминают мне довольно старый анекдот: "Юникс лучше, чем NT! Чем лучше? Чем NT!" Ну а если проще -- налицо полное отсутствие каких-либо аргументов. Компетентности не хватает? Ну, если Вы не в состоянии отличить язык от компилятора этого языка, то Вы действительно абсолютно некомпетентны. Мне вот как-то и в голову не приходит сказать, что Си++ -- плохой язык из-за того, что компилятор от мелкомягких содержит ошибки... Угу. Только на Паскале или Аде надо постараться написать некорректно (а точнее, запутанно), а в Си это само собой легко получается -- например, по рецепту создания "красивых" программ от UbIvItS (когда заголовок цикла используется для кучи всего, кроме собственно управления циклом). Честное слово, иногда складывается впечатление, что программистам, пишущим на Си, дают премии за уменьшение числа символов в исходном тексте программы Он не был решён и не может быть решён, и никакой "очень близости" к машинному коду Си не имеет. Программа на Си точно так же транслируется в машинный код, как и на любом другом ЯВУ. И при одинаковой эффективности компиляторов результат будет одним и тем же. Компилятор Си сгенерирует для i++ команду INC i? Да. Но и компилятор Паскаля для i:= i+1 тоже сгенерирует INC i. Если, конечно, оба компилятора "вменяемые". Но качество компиляторов к качеству языков отношения не имеет. Если б в Си были типы byte, word и т.д., я бы согласился с таким утверждением. Но там типы char и int -- а это высокоуровневые типы, "отвязанные" от конкретного машинного представления: они не задают разрядность явным образом. Да, мне прекрасно известно, что char -- это реально байт, int -- машинное слово "основной" на данной архитектуре разрядности и т.п. Но, тем не менее, они не перестают быть более абстрактными типами, чем "настоящие" байты и слова. Где ж привязанность к низкоуровневым материям? Где отличие от Паскаля? Насчёт абстракций уже сказал выше. Си -- точно такой же "абстрактный" язык, как и Паскаль. Ассемблерные вставки сейчас есть и там, и там. Так в чём реальная разница? Ничего не скажешь: поэт Только асмовское наследие в Си не очень-то прослеживается. Или Вы считаете, что наличие в явном виде операций инкремента и декремента -- это и есть асмовское наследие? Ну так Борланд ввела в Паскаль процедуры Inc и Dec -- чем хуже? Тем, что больше кнопок нажать надо и нельзя их влепить прямо внутрь арифметического выражения? Ну так, к Вашему сведению, в ассемблере их и подавно нельзя влепить внутрь выражения: там каждый оператор -- одна элементарная операция (из-за чего, собственно, и растёт в первую очередь трудоёмкость программирования). Мистическая фраза. Смысл остался для меня загадкой. Хотя постойте, попробую догадаться... Вы, случаем, не пытаетесь сказать, что я дурак, относя Си к ЯВУ в то время как он позволяет напрямую, "низкоуровнево", работать с памятью? Что ж, отвечу. Никакой "низкоуровневой" работы с памятью в Си нет. Как нет и ни в одном другом языке высокого уровня. Память распределяет компилятор, программист точным образом повлиять на это не может (можно лишь "закладываться" на особенности конкретного компилятора -- но этот приём срабатывает в любом языке программирования). Операции с указателями есть и в Паскале, и они точно так же позволяют обратиться к любой области памяти программы, как и указатели на Си. В чём разница? Где низкий уровень? pas Magnum А если человек знает и то, и другое? Вам бегины-енды мешают чтению программы, а мне -- наоборот. И это при том, что был период в жизни, когда я писал в основном на Си/Си++. И вздохнул с большим облегчением, когда смог от него отказаться. Мне бегины-енды нравятся куда больше, чем "шифрограммы" из спецсимволов. Хотя брэйфак в этом плане, конечно, рулит
rei3er Я бы так сказал: бегин-энд или { } -- это вопрос привычки и психологии, и объективной разницы между ними нет. А вот использование в Си одного и того же символа * для двух совершенно разных вещей -- объективно хуже, чем использование разных символов (* и ^) в Паскале. Потому что на "автопилоте" уже не получится понять, что имеется в виду. Опытный программист, конечно, обычно разберётся с этим за доли секунды, на подсознательном уровне, но всё же... А если в одном операторе * встречается несколько раз в обоих значениях? Тогда анализ становится ещё сложнее. Ну и т.д. Ну и плюс я уже говорил в других темах о лёгком возникновении в Си ряда синтаксически корректных, но ошибочных по смыслу конструкций, начисто исключённых в Паскале: = и ==, & и && и т.д.
creeper +1 SII Краткость - сестра таланта (С) Грош цена тому автору, которому для изложения мысли нужно 1000 страниц (С)