Как стать автором
Обновить
23
0

Пользователь

Отправить сообщение

Вся правда о целочисленных типах в C

Время на прочтение3 мин
Количество просмотров138K
Для начала несколько вопросов:

  1. Тип char по умолчанию знаковый или нет? А int?
  2. Законно ли неявное приведение (signed char *) к (char *)? А то же для int?
  3. Сколько бит в unsigned char?
  4. Какое максимальное число гарантированно можно поместить в int? А минимальное?
  5. Тип long определённо больше, чем char, не так ли?

Разумеется, экспериментально искать ответы на эти вопросы с помощью вашего любимого компилятора в вашей любимой системе на вашем любимом компьютере1) — не лучшая идея. Мы говорим о стандарте языка (С99 и новее).

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

Предположу, что вы ответили
  1. Знаковые оба.
  2. Законны оба.
  3. 8.
  4. 2147483647. -2147483648.
  5. Конечно, Кэп.


А правильные ответы такие
  1. char — не регламентируется, int — знаковый.
  2. Для int — законно, а для char — нет.
  3. Не менее 8.
  4. 32767. -32767
  5. Вообще говоря, нет.



Читать дальше →
Всего голосов 74: ↑69 и ↓5+64
Комментарии54

Удаленная переустановка Linux по ssh без доступа к консоли

Время на прочтение8 мин
Количество просмотров60K
Понадобилось мне переустановить сервер, который как бы хостился у знакомых знакомых. Там был сильно устаревший Debian, а, самое главное, система стояла на обычных разделах без lvm и пространство было распределено очень не оптимально. Физический доступ получить к нему было практически нереально, местного админа попросить что-то сделать было можно, но занять это могло неделю. Виртуальный KVM у сервера был, но извне на него попасть было нельзя; у как бы хостера не было лишних IP-адресов, а внутрь его сети попасть было невозможно. Надо было переустановить сервер из-под работающей системы по ssh. Ага, давайте поменяем ротор у турбины не выключая, потом её перезапустим и будет она с новым ротором работать!
Читать дальше →
Всего голосов 111: ↑110 и ↓1+109
Комментарии70

Излучение сотовой связи: опасно?

Время на прочтение5 мин
Количество просмотров97K

Иллюстрация: Abe V. Rotor

Каждый день наш мозг подвергается воздействию излучения от сотовых телефонов, базовых станций, роутеров, спутников, сигнализаций, датчиков движения, радио и телевидения. ЛЭП, проводка в стенах, реликтовое излучение, гранитный щебень — все это может оказывать воздействие на клетки нашего тела. Прежде чем закрываться в клетке Фарадея и шить себе костюм из фольги, давайте посмотрим, о чём говорят нам законы физики и результаты научных исследований.
Читать дальше →
Всего голосов 46: ↑38 и ↓8+30
Комментарии45

Тяжелое расставание с Net-Tools

Время на прочтение7 мин
Количество просмотров100K

Не секрет, что Net-Tools пора на почетную отставку. Да, многим админам и мне в том числе, до условного рефлекса Павлова знакомы команды ifconfig, route, netstat. На первый взгляд нет причин что-то менять, а лучшее как всегда враг хорошего.




Давайте узнаем почему Net-Tools уже не тот и как безболезненно с него перейти на iproute2 .

Читать дальше →
Всего голосов 32: ↑32 и ↓0+32
Комментарии40

Ускоряем передачу данных в localhost

Время на прочтение8 мин
Количество просмотров17K
Сделано в России

Один из самых быстрых способ межпроцессного взаимодействия реализуется при помощи разделяемой памяти (Shared Memory). Но мне казалось не логичным, что в найденных мною алгоритмах, память всё равно нужно копировать, а после перезапуска клиента (причём он допускался только один) нужно перезапускать и сервер. Взяв волю в кулак, я решил разработать полноценный клиент-сервер с использованием разделимой памяти.
Читать дальше →
Всего голосов 23: ↑22 и ↓1+21
Комментарии9

Как приручить дракона. Краткий пример на clang-c

Время на прочтение12 мин
Количество просмотров15K
Однажды, сидя вечером перед компьютером и предаваясь меланхолии и мыслям о бренности всего сущего, я задумчиво набрал в поиске одного крупного сайта по поиску работы аббревиатуру «LLVM», не надеясь, впрочем, увидеть там что-то особенное, и стал просматривать небогатый, прямо скажем, улов.

Как и следовало ожидать, почти ничего особенного не нашлось, однако одно объявление меня заинтересовало. В нём были такие строки:

«Кого мы возьмем «не глядя» или уровень выполняемых задач:
Вы скачали любой open source проект, собираемый при помощи gcc (объем исходного кода более 10 мегабайт) и для самого большого файла cpp смогли построить AST дерево при помощи clang с –fsyntax-only;
Вы скачали любой open source проект, собираемый при помощи Visual C++ (объем исходного кода более 10 мегабайт) и для самого большого файла cpp смогли построить AST дерево при помощи clang с –fsyntax-only;
Вы смогли написать утилиту, которая выделит все места деклараций и использования локальных переменных, а также все функции, не определенные в данном файле
».

Ну что же, подумал я, какое-никакое, а развлечение на вечер.


Читать дальше →
Всего голосов 47: ↑46 и ↓1+45
Комментарии9

Уязвимость «ВКонтакте» позволяла получить прямые ссылки на приватные фотографии

Время на прочтение8 мин
Количество просмотров314K


tl;dr
Была обнаружена уязвимость в закладках ВК, которая позволяла получать прямые ссылки на приватные фотографии из личных сообщений, альбомов любого пользователя/группы. Был написан скрипт, который перебирал фотографии пользователя за определенный период и затем, через эту уязвимость получал прямые ссылки на изображения. Если коротко, то: можно было за 1 минуту получить все ваши вчерашние фотографии, за 7 минут — все фото, загруженные на прошлой неделе, за 20 минут — прошлый месяц, за 2 часа — прошлый год. Уязвимость на данный момент исправлена. Администрация ВКонтакте выплатила вознаграждение в 10к голосов.

История началась с того, как мне в личку во «Вконтакте» кинули изображение. Обычно, если вещь важная, я её загружаю в облако, но в моём случае в этом не было необходимости, и я решил воспользоваться функцией закладок «Вконтакте».
Читать дальше →
Всего голосов 154: ↑150 и ↓4+146
Комментарии58

Отладка вашей ОС: урок по выделению памяти

Время на прочтение13 мин
Количество просмотров27K

Всё началось, как и многие другие расследования, с баг-репорта.

Название отчёта было довольно простым: «При HTTP-подключении iter_content медленно работает с чанками большого размера». Подобное название немедленно включило у меня в голове сирену по двум причинам. Во-первых, довольно сложно определить, что здесь означает «медленно»? Насколько медленно? Насколько велик «большой размер»? Во-вторых, если бы описанное проявлялось действительно серьёзно, то мы бы об этом уже знали. Метод iter_content используется давно, и если бы он существенно притормаживал в распространённом пользовательском режиме, то мимо нас такая информация не прошла бы.
Читать дальше →
Всего голосов 88: ↑78 и ↓10+68
Комментарии21

Превозмогая трудности: Gravity Defied на sed

Время на прочтение5 мин
Количество просмотров9.1K
image Итак, эта статья посвящается тем, кто любит решать нестандартные задачи на не предназначенных для этого инструментах. Здесь я опишу основные проблемы, с которыми столкнулся во время создания аналога игры Gravity defied с использованием потокового текстового редактора (sed).

Далее предполагается, что читатель хотя бы немного знаком с синтаксисом sed'ом и и написанием скриптов под bash.
Читать дальше →
Всего голосов 42: ↑41 и ↓1+40
Комментарии8

В C++17 до сих пор нет нормальных многомерных массивов, которые были в Fortran начиная с Fortran 90

Время на прочтение5 мин
Количество просмотров32K
Это статья про многомерные массивы. А ещё про ключевое слово restrict, до появления которого в C язык Fortran был быстрее C. Немного про то, зачем я это написал, см. в конце.

Многомерные массивы. Начну с многомерных массивов. Допустим, вам нужно максимально эффективно работать с большими квадратными матрицами в C++ (скажем, умножать их друг на друга). Причём размер матриц становится известен лишь в runtime. Что делать?

Всякие double a[n][n] и std::array<std::array<double, n>, n> не сработают, т. к. порядок матрицы (n) будет известен лишь в runtime. new double[n][n] не сработает по этой же причине (лишь первое измерение массива, создаваемого new, может быть runtime-выражением). Попробуем так:

double **a = new double *[n]; // Массив длины n указателей на double
for (int i = 0; i != n; ++i)
  {
    a[i] = new double[n];
  }
Читать дальше →
Всего голосов 84: ↑54 и ↓30+24
Комментарии226

Расширения языков C и C++. Часть 1

Время на прочтение19 мин
Количество просмотров62K
Данная статья (и я надеюсь что серия статей) посвящена нестандартным расширениям языков C и C++, которые существуют практически в каждом компиляторе.

Языковые расширения — это дополнительные возможности и фичи языка, не входящие в стандарт, но тем ни менее поддерживаемые компиляторами. Исследовать эти расширения очень интересно — в первую очередь потому, что они возникли не на пустом месте; каждое расширение — результат насущной необходимости, возникавшей у большого числа программистов. А мне интересно вдвойне — поскольку мне нравятся языки программирования и я разрабатываю свой, часто оказывается что многие мои идеи реализованы именно в расширениях языка. Стандарты языков C и C++ развиваются крайне медленно, и порой, читая описание расширений, так и хочется воскликнуть «ну это же очевидно! почему этого до сих пор нет в стандарте?».

Языковые расширения — это такая «серая», теневая область, про которую обычно мало пишут и мало знают. Но именно этим она и и интересна!

Предварительно могу сказать, что будут рассмотрены компиляторы общего назначения gcc, msvs, clang, intel, embarcadero, компиляторы для микроконтроллеров iar и keil, и по возможности многие другие компиляторы. Больше всего расширений в GCC, что не удивительно — свободная разработка способствует воплощению разных языковых фич. К тому же, информация по расширениям GCC вся собрана в одном месте, а информацию по остальным компиляторам придется собирать по крупицам. Поэтому начнем с GCC.
Читать дальше →
Всего голосов 65: ↑61 и ↓4+57
Комментарии54

Манифест Ричарда Столлмана: How I do my computing

Время на прочтение11 мин
Количество просмотров26K
image

Я использую компьютер Thinkpad X60, в котором FSF ( Free Software Foundation) инсталлировали свободную инициализирующую программу (initialization program, libreboot) и свободную операционную систему (Trisquel GNU/Linux). Это первая компьютерная модель со свободной инициализирующей программой и свободной операционной системой, которая когда-либо поступала в продажу. Поэтому это первый компьютерный продукт, который одобрили FSF (однако не был продан Lenovo).

До этого я несколько лет использовал Lemote Yeeloong. На тот момент это был единственный ноутбук со свободной установочной программой и свободной операционной системой, который можно было купить. Но его никогда не продавали со свободной операционной системой.

До этого я использовал OLPC (One Laptop Per Child) несколько недель. Я перестал, потому что проект OLPC решил поддерживать Windows, а я не хотел этого. OLPC используют особую прошивку для WiFi, поэтому я не мог использовать внутреннее WiFi устройство. Не беда, я использовал внешнее.

Результаты меня беспокоят. Я ожидал увидеть миллионы детей, использующих Windows с OLPC. Вместо этого я вижу, как миллионы детей используют Windows с Intel Classmate.

Раннее я пользовался устройствами полностью на свободных GNU/Linux системах, но там были несвободные BIOS. На протяжении восьми лет я пытался найти способ обойти эту проблему.
Всего голосов 63: ↑42 и ↓21+21
Комментарии73

Самая дорогая однобайтовая ошибка

Время на прочтение7 мин
Количество просмотров5.7K
Предлагаю вашему вниманию перевод недавнего поста в электронном журнале Queue авторства Poul-Henning Kamp.

Ошиблись ли Кен, Деннис и Брайан при выборе использовать NUL-завершенные текстовые строки?

ИТ стимулирует и реализует современную западную экономику. Соответственно мы часто видим заголовки про ошеломляюще огромные суммы денег, связанные с ошибками в ИТ. Какое же решение, связанное с ИТ или КН [компьютерными науками], является наиболее дорогим?
Читать дальше →
Всего голосов 141: ↑115 и ↓26+89
Комментарии169

О фундаментальных ошибках в дизайне языков программирования

Время на прочтение6 мин
Количество просмотров21K
Как-то раз мне на глаза попалась статья о том, что самой дорогой ошибкой в дизайне языков программирования было решение определять окончание строки в C по NULL-байту. Один из вариантов перевода этой статьи на Хабре (хотя я, по-моему, читал другой). Эта статья меня немного удивила. Во-первых, как будто в те времена экономии каждого бита памяти можно было шикануть и выделить ещё 2-4 байта в каждой строке на хранение её размера. Во-вторых, никаких особо катастрофических последствий это решения для программиста не несёт. Ошибок, которые можно по этому поводу совершить я могу придумать целых две: неверно выделить память для строки (забыть место под NULL) и неверно записать строку (забыть NULL). О первой ошибке уже предупреждают компиляторы, избежать второй помогает использование библиотечных функций. Всей-то беды.

Значительно большей проблемой времён дизайна языка С (и затем С++) мне кажется другое — оператор for. При всей его кажущейся безвредности — это просто кладезь потенциальных ошибок и проблем.

Давайте вспомним классическое его применение:

for (int i = 0; i < vec.size(); i++)
{...}

Что же здесь может пойти не так?
Читать дальше →
Всего голосов 72: ↑40 и ↓32+8
Комментарии115

main(){printf(&unix["\021%six\012\0"], (unix)[«have»]+«fun»-0x60);}

Время на прочтение5 мин
Количество просмотров17K

Развлекаемся, «распутывая» код на языке Си

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

image

Когда я в очередной раз просматривал книгу «Expert C programming», я вдруг наткнулся на раздел «light relief» в международном конкурсе на самый запутанный код на Си (IOCCC). Это соревнование по написанию как можно более нечитабельного кода. То, что такие конкурсы устраиваются для Си, наверное, говорит что-что об этом языке. Мне хотелось увидеть работы участников этого соревнования. Не найдя никакой информации в интернете, я решил поискать их самостоятельно.

IOCCC был придуман Стивеном Борном, когда он решил использовать препроцессор Си и написать Unix shell как бы на языке Си, но больше похожем на язык Algol-68, с его явными окончаниями операторов, например:

if
  ...
fi 

Он добился этого, сделав:

#define IF if(
#define THEN ){
#define ELSE } else {
#define FI ;}

Что позволило ему писать так:

IF *s2++ == 0
THEN return(0);
FI

Всего голосов 61: ↑57 и ↓4+53
Комментарии4

Оптимизация кода: память

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

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

image

Иерархия памяти работает, потому что хорошо написанные программы имеют тенденцию обращаться к хранилищу на каком-то конкретном уровне более часто, чем к хранилищу на более низком уровне. Так что хранилище на более низком уровне может быть медленнее, больше и дешевле. В итоге мы получаем большой объём памяти, который имеет стоимость хранилища в самом низу иерархии, но доставляет данные программе со скоростью быстрого хранилища в самом верху иерархии.
Читать дальше →
Всего голосов 80: ↑78 и ↓2+76
Комментарии99

Эксперименты с malloc

Время на прочтение12 мин
Количество просмотров36K
image

Как известно, в современных архитектурах x86(_64) и ARM виртуальная память процесса линейна и непрерывна, ибо, к счастью, прошли времена char near* и int huge*. Виртуальная память поделена на страницы, типичный размер которых 4 KiB, и по умолчанию они не отображены на физическую память (mapping), так что работать с ними не получится. Чтобы посмотреть текущие отображённые интервалы адресов у процесса, в Linux смотрим /proc/<pid>/maps, в OS X vmmap <pid>. У каждого интервала адресов есть три вида защиты: от исполнения, от записи и от чтения. Как видно, самый первый интервал, начинающийся с load address (соответствующий сегменту .text у ELF в Linux, __TEXT у Mach-O в OS X), доступен на чтение и исполнение — очень логично. Ещё можно увидеть, что стек по сути ничем не отличается от других интервалов, и можно быстро вычислить его размер, вычтя из конечного адреса начальный. Отображение страниц выполняется с помощью mmap/munmap, а защита меняется с помощью mprotect. Ещё существуют brk/sbrk, deprecated древние пережитки прошлого, которые изменяют размер одного-единственного интервала «данных» и в современных системах эмулируются mmap’ом.

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

  • оптимально управляет уже выделенной памятью;
  • значительно уменьшает количество обращений к ядру (ведь mmap / sbrk — это syscall);
  • вообще абстрагирует программиста от виртуальной памяти, так что многие пользуются malloc’ом, вообще не подозревая о существовании страниц, таблиц трансляции и т. п.

Довольно теории! Будем щупать malloc на практике. Проведём три эксперимента. Работа будет возможна на POSIX-совместимых операционках, в частности была проверена работа на Linux и на OS X.
Читать дальше →
Всего голосов 59: ↑58 и ↓1+57
Комментарии11

Как спасти принцессу, используя 8(+45) языков программирования, в пятницу

Время на прочтение1 мин
Количество просмотров67K


У вас есть JavaScript. Вы тратите несколько часов на сбор библиотек, настройку node и постройку фреймворка для замка. К тому времени, как вы разберетесь с фреймворком, форт уже будет заброшен, а принцесса переберется в другой замок.



У вас есть С. У вас есть библиотека для замка и для принцессы. В атаку! Вы спасаете принцессу, ее собаку, весь ее гардероб и всё, что она когда-либо съела. Fuck, неужели я забыл null-terminator?
Всего голосов 122: ↑81 и ↓41+40
Комментарии205

Подводные камни Bash

Время на прочтение32 мин
Количество просмотров94K


В этой статье мы поговорим об ошибках, совершаемых программистами на Bash. Во всех приведённых примерах есть какие-то изъяны. Вам удастся избежать многих из нижеописанных ошибок, если вы всегда будете использовать кавычки и никогда не будете использовать разбиение на слова (wordsplitting)! Разбиение на слова — это ущербная легаси-практика, унаследованная из оболочки Bourne. Она применяется по умолчанию, если вы не заключаете подстановки (expansions) в кавычки. В общем, подавляющее большинство подводных камней так или иначе связаны с подстановкой без кавычек, что приводит к разбиению на слова и глоббингу (globbing) получившегося результата.


Читать дальше →
Всего голосов 143: ↑141 и ↓2+139
Комментарии63

Null, великий и ужасный

Время на прочтение5 мин
Количество просмотров126K

Ошибка дизайна


Именно так и никак иначе: null в C# — однозначно ошибочное решение, бездумно скопированное из более ранних языков.


  1. Самое страшное: в качестве значения любого ссылочного типа может использоваться универсальный предатель — null, на которого никак не среагирует компилятор. Зато во время исполнения легко получить нож в спину — NullReferenceException. Обрабатывать это исключение бесполезно: оно означает безусловную ошибку в коде.
  2. Перец на рану: сбой (NRE при попытке разыменования) может находится очень далеко от дефекта (использование null там, где ждут полноценный объект).
  3. Упитанный пушной зверек: null неизлечим — никакие будущие нововведения в платформе и языке не избавят нас от прокаженного унаследованного кода, который физически невозможно перестать использовать.

Этот ящик Пандоры был открыт еще при создании языка ALGOL W великим Хоаром, который позднее назвал собственную идею ошибкой на миллиард долларов.

На самом деле все не так плохо
Всего голосов 56: ↑45 и ↓11+34
Комментарии290

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность