Доброго времени суток, хабровчане.

После многих лет написания, дописания, рефакторинга, дебаггинга своего/чужого кода на C++, и не только, по ряду причин я в конце концов пришел к вот такой системе нотации. Возможно она во многом похожа на венгерскую.

Это небольшое упорядочение уже несколько лет меня реально спасает, пусть и приходится делать несколько дополнительных нажатий клавиш. Жить стало намного легче и голова уже не трещит во время чтения и редактирования кода.

И да, давно хотел узнать, кто какую нотацию использует. Кому интересно прошу под кат.

Префиксы в наименовании идентификаторов


Основная часть имени пишется с прописной буквы.

По порядку следования символа в префиксе:

  1. Пространство использования:

    • g — глобальная переменная;
    • p — параметр функции;
    • v — локальная переменная внутри функции;
    • атрибуты/данные класса не имеют метки пространства использования.

  2. Тип:

    • n — Целое число (integer);
    • f — Число с плавающей запятой (float);
    • c — Символ (character);
    • s — Текстовая строка (string);
    • b — Логический флаг, истина или ложь (boolean);
    • d — Дата и/или время (date/time);
    • m — Карта, набор пар «ключ»-«значение» (map).
    • l — Блокиратор (locker);
    • o — нетривиальный тип (object);

  3. Если это набор значений:

    • a — массив, список, множество (array).

  4. Если это указатель или неконстантная ссылка:

    • r — неконстантная ссылка (reference);
    • i — указатель на объект (pointer).


Правила именования для других идентификаторов


  • MAX_NAME_LEN — константные выражения;
  • E.. — перечисления;
  • i, j, x, y, v1, v2 — a..z0..9, единственный символ с возможно последующей цифрой, временная переменная без особого смысла;
  • getVal, get_value — названия функций/методов, первое слово со строчной буквы, остальные — с прописной, особо ядрёные малыми, через подчёркивание;
  • MyClass/MyType — названия типов/классов — каждое слово с прописной.

Если функция получается более менее громоздкая, то возвращаемое значение именую Ret или Res c сопутствующим префиксом. Например:

std::vector<int> vnaRet{0, 1, 2};

Пример использования
#include <string>

using uint = unsigned int;
using slong = signed long long;
using str = std::string;


// Returns length of textual representation of positive version of Val.
uint intWidth( slong pnVal )
{
  uint vnRet{1};
  slong vnAbs{pnVal < 0 ? ( -1 ) * pnVal : pnVal};
  pnVal = 10;

  while( pnVal <= vnAbs )
  {
    vnRet++;
    pnVal *= 10;
  }

  return vnRet;
}

/* Fills string Dest with textual representation of integer number Val.
 * Returns this Dest as a result.
 * Len will contain the length of result string.
 * Beware of using Dest that points to too short characters array.
 */
char *intToStrW( char *const pciDest, slong pnSour, uint &pnrLen )
{
  uint vnSigned{pnSour < 0 ? 1U : 0U};
  pnrLen = vnSigned + intWidth( pnSour );
  uint vnLen{pnrLen};

  if( vnSigned )
  {
    pciDest[0] = '-';
    pnSour *= -1;
  }

  pciDest[vnLen] = 0;

  while( pnSour )
  {
    vnLen--;
    pciDest[vnLen] = ( pnSour % 10 + '0' );
    pnSour /= 10;
  }

  return pciDest;
}



Мне очень интересны ваши комментарии.

Спасибо за внимание.

Комментарии (57)


  1. Tyiler
    21.09.2018 11:14

    1. префикс 'g_' — глобальная переменная
    постфикс '_' — атрибуты/данные класса

    2. Типы никак

    3. Никак

    4. префикс 'p' (не всегда)


    1. cooltonbek Автор
      21.09.2018 12:30

      Спасибо за ответ.


  1. i360u
    21.09.2018 11:22

    Я, после своих многих лет написания, пришел к следующим выводам:


    1. Постфиксы лучше чем префиксы
    2. Односимвольные идентификаторы только мешают читать код, лучше 2-3 символа
    3. Более одного идентификатора на одну переменную — плохо
    4. Верблюды — рулят


    1. cooltonbek Автор
      21.09.2018 12:33

      Спасибо за ответ.


    1. AntonSazonov
      21.09.2018 13:39

      Я, почему-то, пришел почти к обратным выводам. На половину…
      Чем постфикс лучше? Префикс видно сразу, т.к. он вначале.
      Про один хороший недостаток CamelCase недавно писали в блоге PVS-Studio. Предпочитаю snake_case.


      1. cooltonbek Автор
        21.09.2018 14:03

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


      1. i360u
        21.09.2018 15:35

        Чем постфикс лучше?

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


        1. AntonSazonov
          21.09.2018 17:13

          Собственно, я и говорил про именование. Про тип я ничего не говорил.


          1. i360u
            21.09.2018 19:26

            Ну тут мы ведь вариацию венгерской нотации обсуждаем а не именования вообще.


      1. AntonSazonov
        21.09.2018 17:01

        А за что минусуют?
        Я просто высказал своё мнение и никому ничего не навязываю.


        1. cooltonbek Автор
          21.09.2018 17:04

          Не обращайте внимания на минусы. Оно того не стоит.


  1. CoolCmd
    21.09.2018 11:22

    vnaRet

    я бы написал vanRet

    в каких случаях помогает префикс v?


    1. cooltonbek Автор
      21.09.2018 11:31

      Признак локальности переменной...


      1. AntonSazonov
        21.09.2018 13:26

        Почему не l (local)?


        1. cooltonbek Автор
          21.09.2018 13:30

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


          1. AntonSazonov
            21.09.2018 13:52

            На самом деле, для локальных я просто не использую ни префиксов, ни постфиксов (постфиксы вообще не использую). Для всего остального есть префиксы: g — global, m — member/method и т.д. и т.п…
            Так мне проще понять что переменная без пре/пост — это именно локальная переменная, но есть и исключения…
            Для локальных указателей и ссылок я использую префиксы p и r соответственно.


            1. cooltonbek Автор
              21.09.2018 13:59

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


  1. Wilk
    21.09.2018 11:26

    Здравствуйте!

    Последнее время по большей части следую Google C++ Style Guide с некоторыми модификациями в именовании файлов, в ряде случаев использую статические объекты нетривиальных типов (если уверен, что ничего не сломается — кодовая база детских размеров). Единственные префиксы, которые использую, применяются к параметрам функции:

    • i_ — входные параметры;
    • o_ — выходные параметры;
    • io_ — параметры с двухсторонним потоком информации, если можно так сказать.


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


    1. cooltonbek Автор
      21.09.2018 12:29

      Когда-то давно, когда писал логику внутри оракловой БД на PL/SQL, тоже ставил такое.


      1. Wilk
        21.09.2018 12:31

        Здравствуйте!

        Мой код на plpgsql придерживается сходной нотации. Разве что io_ префикс не используется, а локальные переменные имеют префикс _.


        1. cooltonbek Автор
          21.09.2018 12:36

          Здравствуйте.
          Вполне логично.
          Спасибо за ответ.


  1. Tiendil
    21.09.2018 11:27
    +3

    Вносить тип данных в имя переменной — моветон.


    1. cooltonbek Автор
      21.09.2018 12:27

      Не пользуюсь правилами, которые оказываются на поверку неэффективными.
      Опубликовал это только после 3-4 лет использования, поняв, что так всё таки в перспективе эффективнее.
      Спасибо, что высказали ваше мнение.


      1. sith
        22.09.2018 00:33

        Если говорить, про c#, то это рекомендации от Microsoft

        Одна из проблем — необходимость переименовывать переменную, после изменения типа данных.


        1. Lofer
          22.09.2018 01:22

          Одна из проблем — необходимость переименовывать переменную, после изменения типа данных.

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


        1. cooltonbek Автор
          22.09.2018 18:49

          После того, как в некоторых случаях изменение типа повлекло за собой некоторые довольно труднодиагностируемые баги, я сознательно и намеренно внес тип в название. Как раз чтобы посмотреть все случаи использования этой переменной и предотвратить неверное толкование или нверное использование с изменившимся типом. Не люблю автоматизацию в некоторых местах. Т.е. это в моём случае получается не бага, а фича.
          C++ знаете ли он такой. За ним глаз да глаз нужен. Особеннов во всяких узких местах, оптимизированных на производительность и т.п.


  1. dipsy
    21.09.2018 11:36

    Стараюсь придерживаться чего-то такого:
    type_name, class_name, function_name()
    VariableName, ObjectName, ConstDefinedValue
    eEnumName { eEnumValue, (или просто EnumValue) }

    За некоторыми исключениями, например имя енума могу написать как и type_name, если оно по смыслу ближе к «типу» значения.
    Пристыковывать префиксы из типа и прочих характеристик не считаю нужным, во первых тип может и поменяться, во вторых, очень некрасиво выглядит, хзДобавлять йфМусор к именам, в третьих простые типы почти не использую, вместо int я скорее задефайню typedef int my_type и буду везде использовать my_type, в выбранном контексте, например если он обозначает количество колес: wheels_count WheelsCount= 4.


    1. cooltonbek Автор
      21.09.2018 12:36

      Спасибо за ответ.


  1. avost
    21.09.2018 12:11
    +1

    Зачем это все? Редакторы с подсветкой синтаксиса (а это все редакторы), позволяют прекрасно отделять глобальные переменные от локальных и те и другие от параметров. Выносить в имя переменной информацию о простом типе — вообще какая-то дичь. Зачем? Вы, посмотрев на метод, тут же забываете что у вас там за переменные? Или у вас методы настолько большие, что к середине забываете, что было в начале? Тогда у вас проблема в другом. Плюс имя должно отображать предназначение переменной из которого должен быть понятен тип. Если не ясен, то у вас проблема с именованием, а не с префиксами. А если и этого мало и все равно потребовалось уточнить — опять же редактор подскажет. Ну, и до кучи — если все равно хочется этого головняка с префиксами, то, на мой взгляд, лучше использовать наиболее широко представленный в индустрии вариант, а не изобретать свой велосипед. По армейскому принципу — пусть безобразно, зато единообразно.


    1. cooltonbek Автор
      21.09.2018 12:42

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


      1. sith
        22.09.2018 00:44

        При работе с кучей людей

        А тем более с кучей разных компаний
        в конце концов приходишь пусть не к идеальному, но к определенному своду правил

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

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


        1. Serge78rus
          22.09.2018 10:31

          У Вас начало и конец предпоследнего абзаца несколько противоречат друг другу.


  1. mcferden
    21.09.2018 12:15
    +1

    Майерс говорил, что надо писать type-agnostic код, т.е. так, чтобы не зная ничего о типах данных, я мог понять, что он делает, и какой контракт выполняет. Идентификаторы должны точно и однозначно описывать семантику своего значения. Если соблюдать это правило, то никакие иные соглашения будут не нужны.

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


    1. cooltonbek Автор
      21.09.2018 12:21

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


  1. Serge78rus
    21.09.2018 13:09

    Когда-то давно тоже искал «свой стиль», Интернета тогда не было, поэтому ориентировался на книги и чужой код. В какой-то момент даже показалось, что нашел то, что мне удобно. Потом ко мне попал документ от Борланда о принятых у них правилах именования, очень вдохновило то, что это во многом совпадало с тем, к чему пришел самостоятельно. Одно время даже дошел до маразма переделывать чужой код, с которым предстояло серьезно разбираться, под свой стиль. Со временем это прошло и сейчас читаю чужой код, написанный в любом стиле и это не доставляет мне никакого неудобства.
    Сам придерживаюсь очень ограниченного свода правил, похожих на принятые в Java (пишу в основном на C++ и C, изредка JavaScript):
    -свои типы с большой буквы (библиотечные — как уж есть)
    -все переменные и функции — с маленькой
    -префиксов не использую за редким исключением для указателей (в основном в низкоуровневом C коде) — ptr
    -основное внимание на содержательность имен (иногда даже рефакторю код только из-за переименования неудачно выбранных имен)
    -многословные имена в основном верблюжим стилем
    -однобуквенные имена только для переменных в пределах нескольких строк.


    1. cooltonbek Автор
      21.09.2018 13:24

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


      1. Serge78rus
        21.09.2018 14:00

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


        1. cooltonbek Автор
          21.09.2018 14:06

          Совершенно согласен.


  1. geher
    21.09.2018 16:22

    Обычно просто приспосабливаюсь к нотации, принятой в проекте.
    Если же есть возможность выбирать (для проектов, исполняемых в одно лицо), то никаких префиксов, суффиксов и иных элементов, описывающих тип переменной. Редактор тип подсветит, если надо. А нотация типов в именах переменных только усложняет. Одна-две буквы — совершенно не интуитивно (например, почему целое — это n, а не i, почему один на все целые, а не на каждый размер целого с пометкой наличия знака). Писать тип полностью — перегружается имя, и акцент сильно смещается со смысла переменной на ее тип.
    Использую префиксы — T (тип) и P (тип указателя) для выделения типов, чтобы отличить их от переменных (приучился в Delphi, как-то свыкся и нахожу для себя удобным).
    Предпочитаю верблюжью нотацию, поскольку мной (и не только) она воспринимается лучше альтернатив.
    Не считаю зазорным использовать однобуквенные и сокращенные имена переменных в качестве счетчиков цикла, если нет глубокой вложенности и в случаях, когда оно так давно принято (например, i в качестве счетчика цикла, sin — вместо Sinus, n в качестве количества, если оно именно так прописано в математической модели).


    1. cooltonbek Автор
      21.09.2018 17:10

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


  1. SUA
    21.09.2018 17:18

    CamelCase (и да… регистронезависимый ЯП избавляет от его минуса)
    Типизация в имени переменной в век современных IDE уже немного лишнее, для коллекций есть множественное число


  1. berez
    21.09.2018 17:32
    +1

    В текущем моем проекте такие соглашения:
    — никаких префиксов.
    — из постфиксов — только подчеркивание для дата-мемберов класса (localData_).
    — СamelCase. При этом регистр первой буквы имеет значение: с большой буквы начинаются имена типов, статических и глобальных переменных, статических функций класса. С маленькой буквы — обычные (нестатические) функции-члены класса и всяческие переменные.
    — геттеры и сеттеры оформляются как value()/setValue(newValue) — т. е. никаких get_value() или getValue().
    — для совсем очевидных вещей типа счетчиков цикла разрешено использовать однобуквенные переменные (обычно i). В остальном даже временные переменные должны иметь осмысленное имя.


    1. cooltonbek Автор
      21.09.2018 17:52
      -1

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


  1. Tishka17
    21.09.2018 18:35

    Как хорошо, что в питоне есть pep8


    А в целом согласен с комментариями, что идентификатор должен отражать семантику, а не тип и другую информацию, которая и так доступна в IDE.


    1. nad_oby
      24.09.2018 20:04

      О да pep8 и pylint спасают просто.
      А для языков на которых почти не пишу или рекомендации (если под них линтер настраивается легко) или стиль проекта.


  1. Sun-ami
    21.09.2018 18:43

    Придерживаюсь мнения, что следует стремиться к тому, чтобы код читался как естественный текст. Поэтому в случае, когда я не ограничен корпоративными требованиями — не использую префиксов на C++, за исключением значений emun, где использую сокращение имени типа как префикс. Префиксы сильно мешают произнесению имён, и тем самым затрудняют чтение. Если приходится писать на С (а это бывает редко)- использую префиксы в именах функций и структур вместо имён классов для получения некого подобия C++. Для интерфейсных и долго живущих переменных, и особенно констант, имеющих физическую размерность часто использую суффикс размерности — _ms, _mV, и т.п. Для локальных переменных использую боле короткие имена, чем меньше область использования — тем короче. Использую нотацию CamelCase — с большой буквы для типов, с маленькой — для переменных и функций. getValue setValue.


    1. Serge78rus
      21.09.2018 19:33

      С тех пор, как в C++ появилась возможность использования enum как полноценного типа, надобность в префиксах и для него отпала.


      1. Sun-ami
        21.09.2018 20:57

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


        1. Serge78rus
          22.09.2018 10:21

          Заинтересовало, кто из компиляторов C++ в 2018 году не поддерживает спецификации C++11.


          1. Sun-ami
            22.09.2018 12:40

            Не все используют последние версии компиляторов — в корпоративной среде для этого есть множество причин. А, к примеру IAR стал поддерживать C++11 не очень давно, и с последними версиями есть другие проблемы. Зато оптимизирует хорошо.


            1. Serge78rus
              22.09.2018 13:17

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


  1. MacIn
    21.09.2018 21:02
    -1

    Догматикам — бой.

    Префиксы по области видимости, такие как
    l (local) — локальная переменная
    g (global) — глобальная переменная
    f (field) — поле данных класса
    u (unit) — глобальная в рамках модуля
    c (constant) или ABC_DEF стиль
    s (string constant)
    A — формальный параметр

    Префиксы очень помогают. Видишь какой-нибудь ItemIndex — а что это — формальный параметр? Property? Локальная переменная? А хз, ищи давай. А так

    lItemIndex
    — локальная, все красиво, понятно с одного взгляда.

    Ах, и как упомянули выше
    T (type) — для названия типа или класса
    P (pointer) для имени типа указателя.

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


    1. cooltonbek Автор
      21.09.2018 21:45
      -2

      Спасибо за ответ, отлично оформили свою позицию.
      Всё ясно и понятно.


  1. Lofer
    22.09.2018 01:13

    Критерии достаточно простые:
    1. Должно быть читаемо и понимаемо вне среды разработки и специальных инструментальных средств.
    2. Должно быть самоописываемое и как можно меньше заставлять «расчесывать мозг». В идеале интуитивно поняно.
    3. Должы быть понятны области видимости переменных их типы и жизненный цикл.
    4. Должны быть различимы переменные и функции/методы
    5. Не должны смешиваться символы в описаниях переменных и методов: Iil1.
    6. Локальные переменные и аргументы можно не различать, поскольку на уровне языков или компилятор отловит ошибку или аргумент будет себя вести как локальная переменная (кроме специальных случаев)
    7. Минимально зависимо от языка.

    Простой визуальный тест — открыл написанный код в блокноте и попытался понять, что ты сам писал пару недель назад или твой коллега.
    Обычно используемая нотация: [Scope]['_' delimiter][LifeCircle][(S/s)hortTypeName](VariableName)
    g — global: g_VariableName
    m — module /class: m_VariableName. сокращенный вариант _VariableName
    -local: VariableName

    m_constStrVariableName = «XYZ»
    m_lMaxRandom = 123;
    byte[] btArrIndexes = byte[...]
    double dblAmount= 222
    User userXyz = GetCurrentUser()

    Сейчас применяется в проекте нотация (по требованию заказчика):
    _ — аргументы функций
    l — локальные
    m — класс
    Честно говоря — никакой проблемы такая нотация не решила, а головной боли подкинула, из за смешения символов:
    lIdentity — не воспринимается визуально, поскольку мозг реагирует как на IInterface.
    if (lId ==_id) заставляет «морщит мозг» что бы вчитаться в имена переменных и «на ходу визуально откомпилировать» код. Синтаксически lId & _id ведут себя одинаково в области видимости, но именованы по разному.


  1. Habra_nik
    22.09.2018 18:40

    Интересно, я один такой? За последние пять лет не могу вспомнить места, где не требовали бы писать в строгом соответствии со style guide и рьяно комментили его нарушения во время кода ревью. Я часто оставлял мелкие косячки там-сям, отступ там, чтобы коллегам было что сказать :-).


  1. domix32
    23.09.2018 18:49

    Запилили бы какой-нибудь препроцессор, который атоматически выводил тип из имени переменных


    1. MacIn
      24.09.2018 18:42

      Как-то на ум сразу приходят Бейсик и Фортран.