1. C++ / Говнокод #25901

    +2

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    // https://habr.com/ru/company/jugru/blog/469465/
    // Инициализация в современном C++ 
    // ...
    //Есть примеры ещё более странного поведения этого синтаксиса:
    
    std::string s(48, 'a'); // "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    std::string s{48, 'a'}; // "0a"

    > В первой строке создаётся строка из 48 символов «а», а во второй строка «0а». Это происходит потому, что конструктор string принимает на вход initializer_list из символов. 48 является целочисленным значением, поэтому оно преобразуется в символ. В ASCII число 48 — код символа «0». Это очень странно, потому что есть конструктор, принимающий именно такие аргументы, int и char. Но вместо вызова этого конструктора происходит совершенно неочевидное преобразование. В итоге получается код, который чаще всего ведёт себя не так, как мы ожидаем.

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

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

    Запостил: j123123, 05 Октября 2019

    Комментарии (22) RSS

    • Ох тыж йообаный пиздец...
      int i1;                 //undefined value
      int i2 = 42;            //note: inits with 42
      int i3(42);             //inits with 42
      int i4 = int();         //inits with 42
      int i5{42};             //inits with 42
      int i6 = {42};          //inits with 42
      int i7{};               //inits with 0
      int i8 = {};            //inits with 0
      auto i9 = 42;           //inits with 42
      auto i10{42};           //C++11: std::initializer_list<int>, C++14: int
      auto i11 = {42};        //inits std::initializer_list<int> with 42
      auto i12 = int{42};     //inits int with 42
      int i13();              //declares a function
      int i14(7, 9);          //compile-time error
      int i15 = (7, 9);       //OK, inits int with 9 (comma operator)
      int i16 = int(7, 9);    //compile-time error
      int i17(7, 9);          //compile-time error
      auto i18 = (7, 9);      //OK, inits int with 9 (comma operator)
      auto i19 = int(7, 9);   //compile-time error
      Ответить
      • > int i4 = int(); //inits with 42

        Чиво?
        Ответить
        • Подозреваю, что это опечатка: в скобках должно быть 42.
          Ответить
          • Я уже подумал оно берет последнее значение из стека.
            Ответить
      • > int i13(); //declares a function
        Вот это вот, ИМХО, один из самых каких багров. Именно поэтому я за «def», «function», «defun», «fun», «func» и иже с ними.
        Ответить
        • >> сишник сидел за терминалом со скоростью 9600 и латенси что у твоего модема.
          >> И экран у него был 80 чаров шириной.

          Поэтому «def», «function», «defun», «fun», «func» — непозволительная роскошь. Сишники ведь до сих пор набирают программы на пассивном терминале, подключенном длинной «лапшой» к мейнфрейму.
          Ответить
      • И это, кстати, всего лишь инициализация примитивного инта, тут всё довольно очевидно. А вот когда в бой врывается инициализация сложного объекта с несколькими коньструкторами и полями, инициализированными по-умолчанию — вот тогда начинается жесточайший БДСМ.
        Ответить
      • https://youtu.be/gEx8GH9R13o похоже что стандарты крестов разрабатывают похожим образом.
        Ответить
    • https://blog.tartanllama.xyz/initialization-is-bonkers/
      Ответить
    • Никакого долбоебизма, ты вызываешь два разных конструктора.
      В первом случае ты вызвал нужный конструктор.
      Во втором - конструктор от initializer_list<int>.
      Ответить
      • Это не отменяет того, что кресты по уровню нечитаемости и неочевидности превращаются в «Perl».
        Ответить
        • Мне нравятся конструкции вроде ([](){})(); или ([]<class T>(T x){})(0); — они даже компилируются. А ещё мне нравится http://govnokod.ru/12071
          Ответить
        • Кстати, заметку по «секретным» операторам «Перла» вроде оператора «Сатурн» перевели на русский:
          https://metacpan.org/pod/distribution/POD2-RU/lib/POD2/RU/perlsecret.pod
          Ответить
          • Хуёво как-то перевели:
            Оператор гоатсе предоставляет списочный контекст его правую сторону
            и возвращает количество элементов на ее левой стороне. Обратите внимание, что
            левая сторона должна обеспечивать скалярный контекст; очевидно списочный
            контекст с левой стороны будут получать пустой список в середине.
            Ответить
            • Ага, похоже на гуглопереводчик. Есть и другие переводы:
              http://pragmaticperl.com/issues/06/pragmaticperl-06-секретные-операторы-perl-и-не-только.html
              Ответить
            • Хм. То есть, получается, что постя гоатсе, спамеры даже не предполагали, какой глубокий смысл в нем заключен.
              Ответить
      • Вот только не int, а char, int(48) неявно скастилось в char('0') и

        > Это очень странно, потому что есть конструктор, принимающий именно такие аргументы, int и char. Но вместо вызова этого конструктора происходит совершенно неочевидное преобразование.
        Ответить
        • И ведь использование «{}» для инициализации только массивоподобных объектов (например, если бы «{...}» всегда кастилось в initializer_list) решило бы существенную часть проблем. Но тут внезапно выясняется, что инициализировать объект коньструктором по-умолчанию с помощью простого и понятного синтаксиса «Object hui();» нельзя — мешает багор )))
          Ответить

    Добавить комментарий