1. Си / Говнокод #14627

    +136

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    //...
    float a = 7;
    printf("%d", *(unsigned int *)(&a) >> 23);
    // Что напечатает?
    //...

    На экзамене как-то задали такой вопрос. А ну-ка, кто без компилятора ответит?

    Запостил: GonZaleZ, 18 Февраля 2014

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

    • Экспоненту.
      Ответить
      • Если быть точным - экспоненту и знак. Т.е. 129 если a = 7 и 129+256 если a = -7.
        Ответить
        • P.S. Но, имхо, нахер не нужны такие вопросы на экзаменах. На практике кому нужны эти детали реализации? На практике нужно помнить только длину мантиссы, чтобы не залететь. Да и та в десятичных знаках сойдет. А остальное при необходимости можно посмотреть в спеке.
          Ответить
          • если в курсе проходили IEEE представления чисел с плавающей точкой, то почему и нет. понятно что забудется - но проверить что не лекции не спал и в общих чертах знаешь о чем идет речь надо. у нас в БГУ ФПМ МОВМ как правило на детали реализации сильно не давили, но принцип нужно было понимать досконально. остальное то математически вывести можно.
            Ответить
            • Насколько я помню, стандарт C не требует определённого представления чисел с плавающей точкой. То есть приведённый код может выдать что угодно в зависимости от того, какой стандарт используется.
              Ответить
              • показать все, что скрытоЗначит, так, блядинище ты этакое, запомни: вся та поебень, которую ты написал, мне и в хуй не упёрлась. Оно и понятно - такое тупое говнобольнораспрохуеперепизженное чмо, как ты, ничего умнее этой невероятнейшей хуйни написать и не может. Чего ты, обхуйнок ты говнорожий, пытаешься добиться этой писаниной? Хорошо же, сидя дома, нести всякую херню - всё равно никто хайло не набьёт; но я советую тебе, бляди блядущей да хуй очком сосущей, вести себя как можно тише и не писать всякую хуёвину - зачем выдавать тупость своих родителей, которые, поди, ничем, кроме ебли с обезьянами, и не занимались. Хватит писать хуйню - съебись достойно, чмо. Уповаю на то, что ты поразмыслишь над этим посланием и извлечёшь из него что-нибудь для себя. Прощай, выговнок хуеблядский.
                Ответить
              • Как это не требует? С99 вроде требует поддержки вполне конкретного стандарта, IEEE 754-1985.
                Ответить
              • ISO C ссылается на IEC 60559 который в свою очередь на IEEE 754. QED.
                Ответить
    • UB.

      http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
      Ответить
      • Ну ок, раз уж мы так заботимся об алиасинге:
        float a = 7;
        uint32_t b;
        memcpy(&b, &a, sizeof(float));
        Ответить
        • этот код избавляет от проблем с алиасингом при касте указателей?
          слушай, попробуй в tbarr.h исправить и на гцц пересобрать, может баги исчезнут?
          Ответить
          • А разве в Тарасомассиве есть баги?
            Ответить
            • А мы не с тобой в ЛС на крестофоруме их обсуждали?
              Я двум людям 10 раз сказал, что глюки на ГЦЦ и Интеле, которых нет в Студии - это 95% что из-за тарасомассива, который переосмысливающе преобразует uint8_t* в T*. Они ничего не ответили. Я вот сегодня погуглил - интересно, если я поменяю uint8_t на тупо char, то мне полегчает? Типа там сказали, что для указателей, полученных из char*, компилятор не имеет права считать их заведомо разными.
              Ответить
              • разве uint8_t это не typedef unsigned char?
                Ответить
              • > для указателей, полученных из char*, компилятор не имеет права считать их заведомо разными
                Если я правильно понимаю правила алиасинга - компилятору вообще похуй, каким образом получен указатель.

                Есть у тебя в коде два обращения к данным через два разных указателя (например *p = 42; и int x = *q). Компилятор имеет полное право поменять эти два обращения местами, за исключением описанных в стандарте случаев. А случаи эти - если один из указателей char* или если эти типы целые одного размера (т.е., к примеру, int и unsigned int). (Там вроде еще случаи есть, но я их не помню, прочти список в стандарте).

                А кастовать - да хоть закастуйся, влияют только сами обращения через указатель.
                Ответить
                • Ты уверен, что это единственное место, которое может вызвать проблемы из-за моего каста? Где ещё могут возникнуть компиляторозависимые баги?
                  Ответить
                • Ну и вроде бы в Тарасомассиве ты юзаешь блок данных только как T*, поэтому ничего забаговать не должно... Или не только как T*?
                  Ответить
                  • Только как T*.
                    Ещё несколько раз static_cast от родителя к потомку.
                    Блин, если б у меня был компилятор, который воспроизводит баг, и с которым я умею работать, я б поковырял. А так народ видит, что у меня баг, а копать, конечно же, мой код не хочет, ибо не своё.
                    Ответить
                    • > Ещё несколько раз static_cast от родителя к потомку.
                      Ну если это единичный объект, и ты обеспечил гарантию, что там находится этот потомок - все норм.

                      А вот кастовать массив из Base* в массив из Derived* (да и наоборот тоже) категорически запрещено:
                      Derived *d = new Derived[10];
                      Base *b = d; // компилятор наивно полагает, что это указатель на один объект
                      b[2]->test(); // КРОВЬ-КИШКИ-ПРОЧИТАЛО-ОБЪЕКТ-С-СЕРЕДИНЫ
                      Ответить
                      • показать все, что скрытоЯ твою мать ебал.
                        Ответить
                      • > А вот кастовать массив из Base* в массив из Derived* (да и наоборот тоже) категорически запрещено:

                        нет, такого нет

                        есть
                        EntityPoint 
                        					&ep1 = *static_cast<EntityPoint*>(f.points[f.points.low()+0]),
                        					&ep2 = *static_cast<EntityPoint*>(f.points[f.points.low()+1]),
                        					&ep3 = *static_cast<EntityPoint*>(f.points[f.points.low()+2]);


                        И ещё есть
                        for (int i = entityPoints.low(); i<entityPoints.high(); ++i)
                        			static_cast<Point3D&>(entityPoints[i]) = position.RotateP(entityPoints[i].initialP);


                        Да, и все [i] - это индексы в тарасомассиве
                        Ответить
                  • показать все, что скрытоЯ твою мать ебал.
                    Ответить
                • показать все, что скрытоЯ твою мать ебал.
                  Ответить
              • показать все, что скрытоЯ твою мать ебал.
                Ответить
            • показать все, что скрытоЯ твою мать ебал.
              Ответить
          • показать все, что скрытоЯ твою мать ебал.
            Ответить
        • показать все, что скрытоЯ твою мать ебал.
          Ответить
      • Не расскажете, с чего вас вдруг на сишку потянуло из мягкой и тёплой жабовселенной? Любопытство или жизненная необходимость?
        Ответить
        • Почему сразу "потянуло"? Что, если я пишу на Жабе for a living, мне уже нельзя знать C и интересоваться UB в нём?
          Ответить
        • Недостаток кислорода легкое удушье.
          Ответить
      • >>UB.
        Интуитивно предчувствовал это!
        Ответить
      • показать все, что скрытоЯ твою мать ебал.
        Ответить
    • показать все, что скрытоВсех анально ебал.
      Ответить
    • > А ну-ка, кто без компилятора ответит?
      Я не отвечу, не помню я сколько бит там что значат и с какого числа они нумеруются.
      Я даже не знаю, что означает нулевая экспонента - 1, 0.5, или 2, там кажись сдвиг есть.
      Ответить
    • показать все, что скрытоВсем по минусу, блядища.
      Ответить

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