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

    +129

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    #include <intrin.h>
    #include <stdarg.h>
    #include <stdio.h>
    int func()
    {
    va_list vl;
    int i;
    int arg,Z=1;
    va_start(vl,*(int *)_AddressOfReturnAddress());
    for(i=0;i<5;i++)
        {
             arg=va_arg(vl,int);    
             Z=arg*Z;
        }
     return(Z);
    }
    
    int main(void)
    {
    printf("%d",func(1,2,3,4,5));
    getchar();
    return 0;
    }

    гуру-вычисление факториала пяти одного красавчика с форума wasm.ru... был выведен, как пример функции с переменным числом параметров без единого явного параметра... грязный хак с адресом возврата на стеке - моя идея)))

    Запостил: ReL, 07 Февраля 2011

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

    • fatal error: intrin.h: No such file or directory
      Ответить
      • да... согласен, что непереносимо... интрин есть в msvc (частично в mingw-w64), для других компиляторов можно асмом решить проблему отсутствия _AddressOfReturnAddress... остальное должно быть переносимо по идее...
        Ответить
        • error: ‘va_start’ used in function with fixed args
          Ответить
          • этот гавнокод запостен в разделе "си", так почему, скажите мне, вы его пытаетесь собрать, как "с++" гавнокод? и вообще еррор как-то странно звучит)
            Ответить
            • Именно как C и пытался собрать
              Ответить
              • не знаю, в чем проблема, у меня копипаст собирается без единого ворнинга и работает, как надо (msvc 2010)... покажите командную строку, которой собираете...
                Ответить
                • gcc test.c
                  Ответить
                  • хех... ну наверное гцц вы не собирете)
                    Ответить
                    • Если язык не указан явно, gcc определяет его по расширению файла. А шаманство с разными стандартами: ansi, c99, gnu99 в данном случае не помогло :)
                      Ответить
                      • вообще вместо ва_старта можно использовать что-то типа:
                        #define va_start1(ap, v) (ap = (va_list)(v) + sizeof(void*))
                        если вам хочется под gcc собрать))
                        Ответить
    • Да ну, цифра 5 внутри явно применяется.
      Это не круто.
      Надо чтобы цикл обрывался, как только очередной параметр становится единицей.
      Ответить
      • В поисках 42...
        Ответить
      • а можно ли такое на паскале написать?
        Ответить
        • function mul(a: array of integer);
          var i: integer;
          begin
             result := 1; 
             for i := Low(a) to High(a) do Result := Result * a[i];
          end;
          
          begin
            WriteLn(mul([1, 2, 3, 4, 5]));
          end.
          Ответить
          • и снова костыльный ореп аггау...

            а ведь личинка varargs есть:
            The varargs directive works only with external routines and only with the cdecl calling convention.
            Ответить
          • не... тут весь смысл в функции с переменным числом параметров... паскаль отдыхает)
            Ответить
            • А в чём смысл функции с переменным числом параметров?
              Ответить
              • Сахар-рафинад. Но за Державу Паскаль всё равно обидно.
                Ответить
                • Какой-то коричневый он, этот сахар...
                  Ответить
              • ну просто некоторые вещи становится удобно делать)
                Ответить
            • Дак это код на паскале с переменным числом параметров.
              Ответить
              • я не знаю паскаля, но со стороны это выглядит, как передача массива в параметры... в си++ (где массив в принципе не является стандартным типом языка) можно например создать экземпляр класса массив (из какой-нить библиотеки или самописного) и передать этот экземпляр по указателю, по ссылке или с вызовом конструктора-копирования... это не тоже самое, что переменное число параметров функции, согласитесь... тем более, что при переменном числе параметров - эти самые параметры могут быть разного типа...
                Ответить
                • Только это не создание экземпляра класса, это сборка массива прямо на стеке.
                  Ответить
                  • покажите дизасм этого кода, интересно посмотреть реализацию...
                    Ответить
                    • mov [ebp-24], 00000001
                      mov [ebp-20], 00000002
                      mov [ebp-1c], 00000003
                      mov [ebp-18], 00000004
                      mov [ebp-14], 00000005
                      lea eax, [ebp-24]
                      mov edx, 00000004
                      call mul

                      В стек запихивается массив, в eax пишется адрес массива, (в данном случае пишется указатель на кусок стека, но если так передать динмассив или явно заданный в блоке констант массив, то будет по другому), а в edx пишется длина массива минус 1.
                      Ответить
                      • не, ну в принципе выглядит со стороны нормально, но можно ли таким образом передать массив элементов разного типа?
                        Ответить
              • >Дак это код на паскале с переменным числом параметров.
                Заминусуйте меня. Я не прав. Мне стыдно.
                Ответить
          • //----------------------------------------------
            function mul(a: array of integer);
            var i: integer;
            begin
               result := 1; 
               for i := Low(a) to High(a) do Result := Result * a[i];
            end;
            
            begin
              WriteLn(mul([1, 2, 3, 4, 5]));
            end.

            //----------------------------------------------
            Неа. Так нельзя в D7.
            Зато можно так:
            function mul(a: array of const);
            var i: integer;
            begin
               result := 1; 
               for i := Low(a) to High(a) do Result := Result * a[i];
            end;
            
            begin
              WriteLn(mul([1, "Дельфи говно", 3, "Потому что здесь можно передавать только переменное число констант, а переменные передать нельзя", 5]));
            end.
            Ответить
            • > Неа. Так нельзя в D7.

              лол чё.
              Тебе скрин показать?
              А, я забыл написать function(a: array of integer): integer;
              Ответить
    • Это непортабельное говно
      Ответить

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