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

    −1

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    #include <stdio.h>
    
    int main() {
        char* pituh;
        puts(pituh);
        pituh = "kokoko";
        return 0;
    }

    Угадайте что выведет код?
    ISO и прочим скилловикам просьба воздержаться.

    https://ideone.com/sYrqiB

    Запостил: 3_dar, 29 Мая 2022

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

    • Выведет ко-ко-ко.

      Игра с ранним/поздним присваиванием. Примерно такой же трюк описан в справке по дельфе, с комментарием "присваивание происходит раньше, чем разыменовывание, однако, полагаться на это не стоит".

      Вай ме, чуть напутал. Литералы помещаются в память доступную только для чтения и это происходит много раньше, чем разыменование. Ах-ах, детка, м-м-м... Я кончил!
      Ответить
      • Все не так.

        Хм. Довольно странный трюк. Если закомментировать присваивание, указатель не пуст. Если раскомментировать - пуст. Прога выведет пустую строку.


        program Project1;
        
        {$APPTYPE CONSOLE}
        
        uses
          SysUtils;
        
        var
          P:PChar;
        begin
          WriteLn(inttostr(integer(p)));   // 0
          WriteLn (P);
          P:='Ко-ко-ко';
          Readln;
        end.
        Ответить
    • очевидно же, здесь UB, которое оптимизатор за милую душу вырезает
      Ответить
      • Ответ не верный. Вернее, вообще ответа на вопрос не прозвучало.
        Ответить
        • Нет, верный.
          Ответить
        • Вы хотя бы разделите труд, пишите с разных фаек. А то я уже путаюсь, кто озадачил а кто делает попытки всунуть.
          Ответить
      • Вот и поэтому я за {}
        Ответить
        • Да хотя бы за NULL (извините, nullptr).

          Экономия одной инструкции для инициализации это спичка, и в 99% случаев ты этой экономии даже не заметишь, так что безопаснее всё всегда иинициализировать
          Ответить
        • puts(nullptr) — это тоже UB.
          Ответить
          • разве это не пустая строка?
            Ответить
            • Нет. В puts надо передавать валидную нуль-терминированную строку (как и во всякие printf).
              Ответить
              • а, ок, я еблан
                нужен указатель на ноль, а не нулевой указатель
                Ответить
          • Это другое UB
            Ответить
      • Это не оптимизация.
        Ответить
    • Я думаю, что здесь UB.

      Значение автоматической переменной по умолчанию не определено, так что компилятор имеет право


      1. Выкинуть puts вообще.
      2. Попытаться вывести строку с незвестного адреса, и получить фолт
      3. Однако наверное он имеет право также слить его с шестой строкой, и выдать kokoko

      В принципе, вопрос "что будет делать компилятор в случае UB" не совсем корректен
      Ответить
      • > "что будет делать компилятор в случае UB"

        По-хорошему должен выдавать сигнал «обнаружено UB», чтобы периферийные устройства могли поймать этот сигнал и отреагировать на него. Мне нравится идея чехла на кресло, которорое будет бить током при обнаружении UB.
        Ответить
        • UB для компилятора это не проблема, а возможность же.
          Возможность выпила ненужного говна
          Ответить
        • пришел такой в первый день на новую работу по переписыванию легаси, в голове приятные думки о 10х зарплате, ставишь на стол кофеёк, садишься, запускаешь IDE, ну давайте посмотрим что у вас тут, АХ БЛЯДЬ
          Ответить
          • Файк, а ты сколько получаешь?
            Ответить
            • нисколько, я только теперь могу начать получать статус индивидуального предпринимателя, чтобы перевести заработанное
              Ответить
              • перевести что и куда?
                Ответить
                • > что

                  заработанное!

                  > куда

                  сюда!
                  Ответить
                  • А много у тебя?

                    Мне просто скоро надо будет из Нидеров в Россию переводить бобло, я буду просить коллег со счетами в России скидывать мне на российский счет, а им буду на голландский (им как раз из Роисси в Европку бабло не вывести)

                    Вдруг тебе тоже надо
                    Ответить
                    • Много! Только нюанс в том, что работаю я и вовсе в штатах, так что свинособакистан в уравнении не участвует, и вообще мои счета там налоговая хочет забанить за то, что я им не платил нологи с начала вторжения.
                      Ответить
                    • Какая хавала )))
                      Ответить
      • В этих Ваших крестах компилятор сам решает, какие инструкции выполнять, а какие - нет? Выброс puts говорит о крайне разбалованном оптимизаторе. На хуй такую среду вообще.
        Ответить
    • Воздержался, проверь.
      Правильный ответ: поведение не определено.
      Ответить
    • Где здесь C++, 3_dar?!
      Ответить
    • А так, вангую, что благодаря квиркам кодегена под штеуды говно будет работать корректно.
      Ответить
      • да как блядь? что тут вообще может быть каректново?
        Ответить
        • > говно будет работать корректно
          > говнокорректно
          > говректно
          > говно
          Даже по дедукции ответ отчевиден
          Ответить
    • У меня ещё одна попытка. Очевидно, неявное обнуление объявленных переменных - особенность работы ко-ко-консольных прог.
      Ответить
    • $ gcc /tmp/main.c -o /tmp/main && /tmp/main
      
      $ gcc -O3 /tmp/main.c -o /tmp/main && /tmp/main
      zsh: segmentation fault (core dumped)  /tmp/main

      забавно

      > Угадайте что выведет код?

      без указания компилятора конечно нещитово
      Ответить
      • Забавно что? Что чтение по неизвестному адресу привело к сегментейшн фолту?

        Действительно, забавно и неожиданно. Никогда такого не было, и вот опять
        Ответить
        • Нет, то что сегфолт проявляется выборочно в зависимости от уровня оптимизации. Я ожидаю функционально идентичный выхлоп от компилятора вне зависимости от уровня оптимизации. Да, тут UB, который развязывает руки и позволяет выплюнуть что угодно, но по правилам хорошего тона обе версии должны либо сегфолтить, либо выводить пустоту.
          Ответить
          • >Нет, то что сегфолт проявляется выборочно в зависимости от уровня оптимизации

            Это вообще характерно для UB

            > Я ожидаю функционально идентичный выхлоп от компилятора вне зависимости от уровня оптимизации.

            мм.. а ты же Java программист, да?

            >по правилам хорошего тона

            Дурным тоном считается писать код с UB:)
            Ответить
          • Если бы кот всегда сегфолтил, то его бы тут не было, капишь?
            Ответить
          • > Я ожидаю функционально идентичный выхлоп от компилятора вне зависимости от уровня оптимизации.
            Уж сколько раз твердили миру…

            Программа с «UB» не является корректной. «Правила хорошего тона» распространяются только на корректные программы.
            Когда поведение определено Стандартом — да, компилятор обязан выдавать функционально идентичные программы вне зависимости от уровня оптимизаций (и компиляторы это делают — с поправкой на различные баги, разумеется).
            Когда же ты даёшь компилятору мусор — компилятор выдаёт в ответ мусор. Точка.
            Ответить
          • > Нет, то что сегфолт проявляется выборочно в зависимости от уровня оптимизации

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

              То есть либо ты пишешь по стандарту и по модели памяти, либо завязываешься на фазу луны
              Ответить
          • > функционально идентичный выхлоп

            Не совсем. Идентичность выхлопа ожидается только на наборах данных, на которых не триггерится UB. Остальные случаи не имеют смысла и не рассматриваются.
            Ответить
            • Во, нашла цитату из умной книжки:

              We say that a program c1 approximates a program c2 when, for each of the initial states for which c1 terminates, c2 also terminates and produces the same final state [1].

              Вот собственно этой аппроксимацией и занимается конпелятор крестов. А для UB'ов стандарт просто не описывает операционную семантику.

              [1] Software Foundations, Volume 2: Programming Language Foundations, Program Equivalence
              Ответить
              • Чем аппроксимация отличается от интерполяции?
                Ответить
      • > zsh
        будь здоров
        Ответить
    • Азаза, я подглядел и оказалось, что угодал выше!
      Как на ideone опции копулятора подергать?
      Ответить
    • Привет! Меня зовут Жан, мне 17 лет, я senior Java-разработчик в Beeline Казахстан и ученик 11 класса (из 12-ти) Назарбаев Интеллектуальной школы (НИШ) физико-математического направления в Алматы.


      https://habr.com/ru/company/beelinekz/blog/667878/


      Джава очень удобный язык, даже 17-тилетний парень может стать сенёром
      Зачем вы пишете на своем сложном си??
      Ответить
    • Говношка, так что в итоге выведет код и в чем был буг?
      Ответить
      • Умри
        Ответить
        • Неправильный ответ. Правильный ответ вообще еще не прозвучал.
          Ответить
          • "Я думаю, что здесь UB."
            "очевидно же, здесь UB"
            "Правильный ответ: поведение не определено."

            Ну или, если вопрос "угадайте", то есть "угадайте, что выведет код в некоторых условиях, которые находятся по ссылке", то первый коммент:
            "Выведет ко-ко-ко.". Потому что иначе зачем эта строчка.
            Ответить
            • Ну как это не определено поведение, если указатель явно нилится?
              Причем только в консольи. В обычной, нормальной проге с гуем был бы заведомый вылет либо мусор на выхлопе. А тут - 0. Ниль, блять, ниль. Кто его занилил и зачем?
              Ответить
              • Ну то есть ответ зависит от интерпретации. Типа сидело 7 воробьев, кошка съела одного, сколько осталось...
                Ответить
                • чувак, ты вообещ в курсе, что ты пиздишь с уёбком, педофилом и дельфистом из Осетии?
                  Ответить
                  • Если ты пиздишь с уёбком, педофилом и дельфистом из Осетии, то, возможно, он делает то же самое.

                    Еще бы знать всех уёбков, а то иногда отвечаешь на нормальный комментарий, а тебе говорят, что ты пиздишь с уёбком, педофилом и дельфистом из Осетии и не соблюдаю cancel-культуру. А я взрослый дядя и крестовик-насильник из России - жаль! если бы я был маленьким мальчиком из Осетии, я бы попросил его тоже научить меня программировать на дельфи.
                    Ответить
                    • > Если ты пиздишь с уёбком, педофилом и дельфистом из Осетии, то, возможно, он делает то же самое.

                      Цитата из неизданных трудов Ницше?
                      Ответить
              • где указатель нилится? ничего он не нилится
                Ответить
                • ХЗ его, какова реализация консоли в ++ и делфях, но думаю, на уровне вызова стандартных IO приблуд отличия минимальны. Этот код выведет пустую строку.


                  program Project1;
                  
                  {$APPTYPE CONSOLE}
                  
                  uses
                    SysUtils;
                  
                  var
                    P:PChar;
                  begin
                    WriteLn (P);
                    P:='Ко-ко-ко';
                    Readln;
                  end.


                  // а не проверить ли нам, что в указателе?
                  program Project2;
                  
                  {$APPTYPE CONSOLE}
                  
                  uses
                    SysUtils;
                  
                  var
                    P:PChar;
                  begin
                    WriteLn(inttostr(integer(p)));   // в консоль будет выведено 0
                    WriteLn (P);
                    P:='Ко-ко-ко';
                    Readln;
                  end.
                  Ответить
            • puts(pituh);

              "Правильный ответ: поведение не определено."
              Да ну на хуй! А мы тут пыжимся, хуячим, изображаем знатоков.
              Ответить

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