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

    +135

    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
    #include <stdio.h>
     
    typedef void(* file_handler_t)(FILE* fileHandle);
     
    void using_file(FILE* fileHandle, file_handler_t fileHandler/*a*/)
    {
        if(!fileHandle)
            return;
        fileHandler(fileHandle);
        fclose(fileHandle);
    }
     
    int main(void) {
        using_file(fopen("myfile.txt","w"),
            ({void body(FILE* fileHandle) {
                /*пишем в fileHandle;*/
            }; body;})//b
        );
            return 0;
    }

    Постю код в защиту курочки от нападок Тараса про автодестукторы. Уникальные виды куриц нужно оберегать, сохранять и защищать.
    Курочка об gnuцицизмы уже зашкварился так что будем стоять на своем до конца. Главное чтобы он свой не отстоял, а то потом не встанет.
    http://ideone.com/2zRuK0

    В позицию /*a*/ можно добавить параметр, деструктирующий объект должным образом. И соответственно оформить using_file как USING макросом, чтобы можно было деструктить объекты не только типа FILE* но и любых других. В макросе вполне при этом может понадобится гнутый typeof, но у нас и так зашквар, так что уже не важно. Так же для полной универсальности можно добавить параметр, определяющий неуспешность открытия объекта, чтобы вместо if(!fileHandle) был if(predicate(fileHandle)). Но конечно при этом лучше просто сделать 2 варианта макроса: обобщенный и с предикатом по умолчанию логическое отрицание.

    Вместо некрасивой позиции //b лучше завести макрос, эмитирующий нормальную красивую человеческую лямбду.

    Запостил: LispGovno, 16 Июня 2013

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

    • "Всем-всем! Из порта "Бригиди"выслан прямо с манежа...
      ...на помощь нашему укротителю вертолет с местным укротителем."
      Ответить
    • если настоять на своем, то вкус получится довольно странным...
      Ответить
    • Блин, nested function в блоке посреди выражения... Хаскель плохо на тебя влияет ;)

      > эмитирующий
      Чего это макрос у тебя испускает?
      Ответить
      • Она нихуя не нестед, у вложенной другой список параметров (есть параметр - указатель на стек внешней функции).
        Это тут компилятор распознал отсутствие обращений к переменным исходного блока, или просто повезло что не упало?
        Ответить
        • Этот код работает, причем работает так, как тебе не снилась, ибо это умеет гцц. Никаких стеков тут нет, ничего - это макрос.

          open();
          твой код, который ты передал;
          close();

          Никаких функий, блоков. стеков тут нет.
          Ответить
          • Где макрос-то?
            Ответить
            • Ну вот так - для гцц это макрос. using_file() - инлайнится, file_handler_t - инлайнится. Всё инлайнится, указатели на функции и функции выпиливаются. Будет только то, что я тебе написал.
              Ответить
              • Не путай инлайн и макрос, первое - средство оптимизации, второе - просто ковырялка над текстом программы.
                Пока что я вижу, что то ли
                в АСТ-дереве мы передаём по указателю процедуру с неверным списком аргументов, то ли передаваемая процедура не ведёт себя как вложенная.
                Кстати, в этом фрагменте нет ни одного слова inline, потому что компилятор умнее всяких курочек.
                Ответить
                • > в АСТ-дереве мы передаём по указателю процедуру с неверным списком аргументов,
                  Откуда трава? Ничего подобного.

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


                  Иногда он не инлайнит то, что нужно - допустим он у тебя есть цикл, для тех же дифуров. тысяич шагов по сетке 1к*1к. Обработку сетки я анрольнул в функции - получилась функция килобайт на 8. Конпелятор её не инлайнит, хотя она вызывается тысячи раз, что даёт тонных оверхеда. Написал инлайн - стало работать в 2раза быстрее.


                  Поэтому пацаны лучше знают, что надо и когда инлайнить. На лоре был мой тред про L1i.
                  Ответить
                • Тут всё передаётся правильно - ты запиливаешь функцию внутри блока ({}), а потом возвращаешь её. Список аргументов тут правильный.
                  Ответить
                  • > ты запиливаешь функцию внутри блока ({}), а потом возвращаешь её.
                    Я реализовал по твоим заветам, так что в этом объяснении не было смысла.

                    Лучше раскажи как компилятор не заинлайнив эту функцию сможет обращаться к локальной переменной tarasB в стеке текущего потока? Или если заинлайнить не получится, то будет облом с обращением к переменной и не скомпилируется?
                    Ответить
                    • http://gcc.godbolt.org/#%7B%22version%22%3A3%2C%22filterAsm%22%3A%7B%22labels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue%7D%2C%22compilers%22%3A%5B%7B%22source%22%3A%22%23include%20%3Cstdio.h%3E%5Cn%20%5Cntypedef%20void(*%20file_handler_t)(void)%3B%5Cn%20%5Cnvoid%20using_file(file_handler_t%20fileHandler)%5Cn%7B%5Cn%20%20%20%20fileHandler()%3B%5Cn%7D%5Cn%20%5Cnint%20main(void)%20%7B%5Cn%20%20%20%20int%20tarasB%3D%7B0%7D%3B%5Cn%20%20%20%20using_file(%5Cn%20%20%20%20%20%20%20%20(%7Bvoid%20body(void)%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2F*пишем%20в%20fileHandle%3B*%2F%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%2B%2BtarasB%3B%5Cn%20%20%20%20%20%20%20%20%7D%3B%20body%3B%7D)%2F%2Fb%20%20%20%20%5Cn%20%20%20%20)%3B%5Cn%20%20%20%20%2B%2BtarasB%3B%5Cn%20%20%20%20fprintf(stdout%2C%20%5C%22%25i%5C%22%2C%20tarasB)%3B%5Cn%20%20%20%20%20%20%20%20return%200%3B%5Cn%7D%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fclang%2B%2B%22%2C%22options%22%3A%22-O0%20-march%3Dnative%20-std%3Dgnu99%22%7D%5D%7D


                      Кто тут достаточно скилед и сможет врубить возможность анализа кода С без ++?

                      И ещё я помню были похожие сервисы. Может на них удастся код сгенеренный посмотреть?
                      Ответить
                    • Если ты юзаешь тарасаБ, то даже с O0 гцц инлайнит. Значит пацаны и это предусмотрели. Да я не знаю как там заинлайнить не получится - я не могу придумать.
                      Ответить
                      • Укажи атрибут noinline и проверь
                        Ответить
                        • Один фиг абдурил - он заинлайнил функцию до вызова, а using_file() превратил в джамп на то, что он заинлайнил.
                          Ответить
                          • Круто! Если есть желание поэкспериментировать, то можешь сделать массив на 3 немного разных подобных функций и выбирай по rand случайную из них. Неужели и с подобным справится?
                            Ответить
                            • Рандомную из массива - он конечно же не заинлайнит. А там вычисляемую из массива - инлайнит, кстати тут в консте есть смысл.
                              Ответить
            • На тебе макрос:
              #include <stdio.h>
               
              #define LAMBDA(return_type, args, body) ({return_type bodyf##__LINE__(FILE* fileHandle) {body;}; bodyf##__LINE__;})
               
              typedef void(* file_handler_t)(FILE* fileHandle);
               
              void using_file(FILE* fileHandle, file_handler_t fileHandler/*a*/)
              {
                  /*if(!fileHandle)
                      return;*/
                  fileHandler(fileHandle);
                  //fclose(fileHandle);
              }
               
              int main(void) {
                  int tarasB={0};
                  using_file(fopen("myfile.txt","w"),
                      LAMBDA(void, (FILE* fileHandle),
                          ({
                              /*пишем в fileHandle;*/
                              ++tarasB;
                          })
                      )
                  );
                  ++tarasB;
                  fprintf(stdout, "%i", tarasB);
                      return 0;
              }


              http://ideone.com/O6a6pd

              PS: А, вы не об этом... Тогда разбирайтесь сами.
              Ответить
        • > отсутствие обращений к переменным исходного блока
          Если тебя интересует есть ли в коде этой функции замыкания на локальные переменные, то конечно есть, как и в любой нормальной лямбде, пусть в данном случае лямбде для бедных.
          #include <stdio.h>
           
          typedef void(* file_handler_t)(FILE* fileHandle);
           
          void using_file(FILE* fileHandle, file_handler_t fileHandler/*a*/)
          {
              /*if(!fileHandle)
                  return;*/
              fileHandler(fileHandle);
              //fclose(fileHandle);
          }
           
          int main(void) {
              int tarasB={0};
              using_file(fopen("myfile.txt","w"),
                  ({void body(FILE* fileHandle) {
                      /*пишем в fileHandle;*/
                      ++tarasB;
                  }; body;})//b    
              );
              ++tarasB;
              fprintf(stdout, "%i", tarasB);
                  return 0;
          }

          http://ideone.com/1SSYXf
          Ответить
          • Ну они не совсем замыкания. Гарантированное время жизни у них ограничено временем жизни родительского блока.

            P.S. Если, конечно, не писать в стиле Царя, который срал на эти ваши гарантии. Работает в частном случае - и ладно.
            Ответить
            • Оно работает во всхе случаях, ести ты будешь юзать не как питух. Если ты понимаешь, как работает твой код и твой конпелятор - ты никогда не напишешь так, что это не будет работать - это аксиома.


              Царь не обязан писать код для питохов, я не заидушный питух на конвейере. Я пишу код для людей своего, либо выше скилла. И не юзать фичи только из-за того, что какой-то анскильный питух их не осилил - я не собираюсь.
              Ответить
          • И где эти замыкания передаются? Я не вижу этого секретного параметра.
            Ответить
            • Он захватывает все переменные, которые у тебя доступны в это и глобальной области видимости. Считай этот код, как макрос в который ты передаёшь код, который вставится между fopen(); и fclose();
              Ответить
              • Я не с тобой разговариваю, заткнись :D
                Ответить
                • На годболте не могу проверить код сишный. Только крестовый без гнуцецизмов, а это не подходит. Но если он прав, то инлайна достаточно чтобы не передавать ссылку на блок с локальными переменными.

                  Был ещё один сервис, похожий на годболт. Не помнишь его названия? Может там удасться проверить си с гнуцицизмом.
                  Ответить
                  • LWS умел -S, пока работал...
                    Ответить
                    • Ещё один был. Точно помню. По возможностям близкий к годболту. На гейдеве кто-то использовал
                      Может тот, кто все свои коннекторы рекламировал?
                      Ответить
                      • картонужник
                        не знаю, я на гейдев не заходил уже давно
                        форум с донатом это тупость
                        Ответить
                        • > форум с донатом это тупость
                          Эм, там теперь платить надо за участие?
                          Ответить
                          • нет, если ты задонатил, то у тебя типа малиновые штаны и не дай бог такого человека нахуй послать
                            деньги там ни о чем, порядка литра пива, но не вижу смысла
                            Ответить
                            • Налог на флеймы
                              Ответить
                              • точно подмечено

                                при этом никому нельзя употребить слово дельфин (а также афалина, белуха - вообще никак)
                                думаю, главного модераста в детстве укусил дельфин, пока он при фотографировании ему пальцем дыхало заткнул - теперь детская травма преследует всю жизнь

                                скоро дойдут до того, что щеночки и котятки станут вне закона

                                страшно подумать, если бы туда поциент сунулся со своими петушками, курочками и мелкими яйчишками второго сорта
                                Ответить
                                • > мелкими яйчишками второго сорта
                                  О. Точно. Почему я пишу ему курочка... Теперь буду писать цыпленочек.
                                  Ответить
                                • Дельфин...
                                  http://www.mysql.com/common/logos/logo-mysql-110x57.png
                                  Ответить
                              • после того как введен налог на флеймы, вы стали меньше флеймить. Это возмутительно!
                                https://www.youtube.com/watch?v=RQWwTrR5sAk
                                Ответить
                            • А, т.е. можно задонатить и устраивать флеймы на 300 страниц? Круто, че. :)
                              Ответить
                  • Что это за блядокод, работающий лишь от наличия инлайна?
                    Ответить
                    • Инлайн везде есть. ЧТо за код работающий от наличия call'а, а что за тарас работающий лишь от наличия питушиного мозга?

                      А что за сишка, который работает только лишь от наличия конпелятора?
                      Ответить
                      • Инлайн - это средство оптимизации, а если от него зависит логика, то это питушиный код.
                        Ответить
                        • Реально? Питух, иди читай с99. Это часть логики. Инлайн всегда встраивается - т.е. если ты напишешь в функции инлайн - это функция равна макросу и её область видимости - это всё, что ты можешь юзать в блоке, в котором ты её определяешь - по стандарту.


                          Т.е. логика локальной инлайн функции - это область видимости там, где ты её создал, а т.к. это инлайн - это не функция, а макрос, т.е. она лишена поведения функции(она ничего не принимает и не возвращает, а так же на твоём питух call abi - она не будет его юзать).


                          Так же - питух, инлайн ничем не отличается от макросов и на нём можно строить логику.


                          Для питухов, которые еле-еле осилил с89 на уровне 3-тиклассника - это "оптимизация", ибо питухи не могут это юзать.


                          Так же - я могу строить логику на оптимизаторе - на этом построена половина логики glibc. Это компилтайм ветвления и прочее.


                          А ты, анскильный питух - дальше кукарекай.
                          Ответить
                          • > т.е. если ты напишешь в функции инлайн - это функция равна макросу и её область видимости - это всё, что ты можешь юзать в блоке, в котором ты её определяешь - по стандарту.
                            inline void kokoko()
                            {
                              --a;
                            }
                            
                            int main ()
                            {
                              int a=1;
                              kokoko();
                              return a;
                            }

                            http://ideone.com/qaXqce
                            нихуя, не компилится
                            Ответить
                            • Кста, он имеет в виду локальную функцию (которых в стандарте, кстати, нет). И блок в котором она объявлена. Там да, гцц должен позволить юзать переменные. Но вовсе не потому, что она инлайн.
                              Ответить
                              • Я и не говорил, что можно юзать из-за инлайна. Инлайн тут притом, что 100% небудет никакой питушни со стеками и мешанины с регистрами. Без инлайнов тот код был бы уродской питушнёй.

                                >это область видимости там, где ты её создал,
                                Это относится к ЛОКАЛЬНОЙ.

                                >а т.к. это инлайн - это не функция, а макрос, т.е. она лишена поведения функции(она ничего не принимает и не возвращает, а так же на твоём питух call abi - она не будет его юзать).
                                А это уже к инлайну.
                                Ответить
                            • Питамучто область видимости у твоей функции глобальная - создай её после a=1; - будет работать.

                              typedef void(*f_ptr_t)(void);
                              
                              f_ptr_t p;
                              
                              int main() {
                                int tarasB = 0;
                                void inc_tras(void) {
                                  ++tarasB;
                                }
                                inc_tras();
                                p = ({ void inc_trasB(void) { ++tarasB; }; inc_trasB;});
                                
                                p();
                                
                                fprintf(stdout, "%d\n", tarasB);
                                return 0;
                              }


                              Почему ты думаешь, что юзать это в каких-то там хаскелях - это норм, а в сишке типа не норм?
                              Ответить
                              • Да, а причём тут инлайн? Это типичная вложенная функция, неявно принимающая первым параметром указатель на стек внешней функции.
                                И что за прикол в 8-символьных идентификаторах?
                                Ответить
                            • http://ideone.com/3msDrh

                              Починил. Он же пишет, что область видимости - это всё, что ты можешь юзать в блоке, в котором ты её определяешь, а не в том, из которого вызываешь.
                              Ответить
                              • > Починил. Он же пишет, что область видимости - это всё, что ты можешь юзать в блоке, в котором ты её определяешь, а не в том, из которого вызываешь.

                                Да, все верно. Но инлайн здесь соверщенно не при чем.
                                Ответить
                                • Остался один вопрос - как изначальный код работает? Вложенная функция имеет другую сигнатуру и другой тип, чем та функция, которую надо передавать в юзинг. Что там происходит, костыль, везение?
                                  Ответить
                                  • Это воид с одним аргументом FILE *. Такая сигнатура и у указатели и у функции, которая туда записывается.
                                    Ответить
                                    • У вложенной функции появляется ещё один аргумент, если она работает с переменными внешней функции.
                                      Ответить
                                  • > Вложенная функция имеет другую сигнатуру и другой тип, чем та функция, которую надо передавать в юзинг.
                                    Да как это. Функция void (FILE*) и указатель void (*)(FILE*). Почему не передаст то?
                                    Ответить
                                    • Блин, ты знаешь, как вложенные функции реализованы?
                                      У ней сигнатура нихуя не void(FILE*)
                                      У неё сигнатура
                                      void(void* outer_stack, FILE* handle).
                                      Без первого параметра она не сможет обращаться к переменным внешнего блока, потому что переменные внешнего блока адресуются от вершины стека, а после вызова вложенной функции вершина стека сдвигается.
                                      Ответить
                                      • Для этого и нужен инлайн, чтобы этой питушни небыло. Дак это уже прерагатива гцц.
                                        Ответить
                                      • > Блин, ты знаешь, как вложенные функции реализованы?
                                        Да. В gcc они сделаны не так как в пасцале, в котором такие указатели несовместимы ;) Поэтому у нее сигнатура совпадает (даже без инлайна).

                                        http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
                                        Ответить
                                        • > В gcc они сделаны не так как в пасцале,

                                          То есть у них сигнатура совпадает что ли?
                                          А как же тогда к переменным внешней функции обращаться?
                                          Адрес относительно своей вершины стека отсосёт, если сделать рекурсивную вложенную функцию.
                                          Ответить
                                          • Может быть, дело в cdecl, у которого, в отличие от других схем вызова, говно чистит вызывающая подпрограмма, а не вызываемая, что позволяет сишным функциям использовать переменное количество параметров?
                                            Ответить
                                            • Никакая конвенция не поможет на рекурсивных вложенных функциях, стек будет расти, расстояние от переменных внешней функции до вершины стека тоже будет меняться, как его можно вычислить - я ваще не понимаю.
                                              Ответить
                                              • А проверить, как оно работает?

                                                Пишем говно:
                                                #include <stdio.h>
                                                
                                                void pituh(int n) {
                                                  int i, j;
                                                  int fact(int x) {
                                                    i = x;
                                                    if (x > 1) {
                                                      j = x * fact(x - 1);
                                                    } else {
                                                      j = 1;
                                                    }
                                                    printf("i = %d, j = %d\n", i, j);
                                                    return j;
                                                  }
                                                
                                                  printf("%d! = %d\n", n, fact(n));
                                                  }
                                                
                                                int main() {
                                                  pituh(10);
                                                }


                                                Компилируем:
                                                _fact.1662:
                                                	pushl	%ebp
                                                	movl	%esp, %ebp
                                                	pushl	%ebx           ; будем юзать ebx, поэтому сохраняем
                                                	subl	$20, %esp      ; резервируем питушню
                                                	movl	%ecx, %ebx     ; в ebx теперь адрес локальных переменных внешней функции
                                                	movl	8(%ebp), %eax
                                                	movl	%eax, 4(%ebx)  ; i = x;
                                                	cmpl	$1, 8(%ebp)    ; if (x > 1)
                                                	jle	L2
                                                	movl	8(%ebp), %eax
                                                	decl	%eax
                                                	movl	%eax, (%esp)   ; передаём (x-1) через стек
                                                	movl	%ebx, %ecx     ; передаём адрес лок. переменных через ecx
                                                	call	_fact.1662
                                                	imull	8(%ebp), %eax  
                                                	movl	%eax, (%ebx)   ; j = x * fact(x - 1);
                                                	jmp	L3
                                                L2:
                                                	movl	$1, (%ebx)     ; j = 1;
                                                L3:
                                                	movl	4(%ebx), %eax
                                                	movl	(%ebx), %edx
                                                	movl	%edx, 8(%esp)  ; в стек j
                                                	movl	%eax, 4(%esp)  ; в стек i
                                                	movl	$LC0, (%esp)   ; в стек адрес константы "i = %d, j = %d\12\0"
                                                	call	_printf
                                                	movl	(%ebx), %eax   ; j в результат
                                                	addl	$20, %esp      ; чистим питушню
                                                	popl	%ebx           ; восстанавливаем ebx
                                                	leave
                                                	ret
                                                ...
                                                _pituh:
                                                	pushl	%ebp
                                                	movl	%esp, %ebp
                                                	subl	$40, %esp       ; резервируем питушню
                                                	leal	-16(%ebp), %eax ; в eax теперь адрес локальных переменных
                                                	movl	8(%ebp), %edx
                                                	movl	%edx, (%esp)    ; n в стек
                                                	movl	%eax, %ecx      ; передаём адрес локальных переменных через ecx
                                                	call	_fact.1662
                                                	movl	%eax, 8(%esp)   ; fact(n) в стек
                                                	movl	8(%ebp), %eax
                                                	movl	%eax, 4(%esp)   ; n в стек
                                                	movl	$LC1, (%esp)
                                                	call	_printf
                                                	leave
                                                	ret

                                                Итого: на x86 gcc использует регистр ecx для передачи во вложенную функцию адреса блока локальных переменных. Т. е. это будет работать даже на рекурсивных функциях.
                                                Ответить
                                                • > А проверить, как оно работает
                                                  Ну здесь указатель на вложенную функцию не юзался, неинтересно ;) С ним код получается прикольней.
                                                  Ответить
                                                • Помести 2 функции fact или condensed_milk в зависимости от числа параметров командной строки argc в pituh_ptr и после вызывай по указателю pituh_ptr одну из этих функций.
                                                  Ответить
                                                  • > вызывай по указателю pituh_ptr одну из этих функций
                                                    call ___enable_execute_stack

                                                    Ужас! Теперь ещё придётся разбираться, как работают трамплины.
                                                    Ответить
                                                    • Код запоси. Местные Хакера, Питухи и Цари разберутся.
                                                      Ответить
                                                    • > Ужас! Теперь ещё придётся разбираться, как работают трамплины.
                                                      Да там тупо. В стек высираются 2 команды:
                                                      mov ecx, адрес родительского контекста
                                                      jmp точка входа в локальную функцию
                                                      Адрес высранного трамплина затем юзается как адрес локальной функции, чтобы его куда-нибудь передать. Естественно при выходе этого трамплина из скопа вызывать его мягко говоря нехорошо, и так будет делать только царь, знающий, что никто не успеет его затереть новыми данными.
                                                      Ответить
                                                    • На x86_64, кстати, такая же херня с генерацией опкодов в стеке.

                                                      P.S. Т.е. питушня программа, юзающая указатели на вложенные функции, из-за исполняемого стека имеет больше шансов на эксплойт, чем любая другая.
                                                      Ответить
                                                      • DEP винды не против такого питушения с исполняемым стеком?
                                                        Ответить
                                                        • > DEP винды не против такого питушения с исполняемым стеком?
                                                          А вот всяко против. И екзек-шилды в линухе тоже. Поэтому указатели на локальные функции - питушня.
                                                          Ответить
                                                          • Вот блин. Питушня какая-то... А я думал в недокрестах нормально функции с контекстом реализовали...
                                                            Ответить
                                                            • > нормально функции с контекстом реализовали...
                                                              А их сделать на самом деле можно только двумя способами - или настоящий указатель на функцию, и новая функция на каждый инстанс, как и сделано здесь или в лиспах. Или вместо указателя на функцию надо передавать нечто более сложное, например указатель на объект, в котором есть замкнутые переменные + указатель на функцию, как это делается в крестах, хаскеле и .т.п.

                                                              Причем второй способ нельзя юзать в качестве колбеков для классических сишных функций, т.к. там нихрена не указатель на функцию. Именно поэтому в gcc и выбрали первый.
                                                              Ответить
                                                              • Ещё можно в глобальной области как-то что-то хранить, наверное.
                                                                Ответить
                                                                • > Ещё можно в глобальной области как-то что-то хранить, наверное.
                                                                  Маловероятно. Очень маловероятно. Не могу придумать способа, чтобы сделать функцию, содержащую вложенные реентерабельной. Контекст ведь нужен не последний, а именно тот самый, в котором брали указатель на локальную функцию.
                                                                  Ответить
                                                          • Так оно что там, флаги на запись и исполнение что ли на ходу правит?
                                                            Ответить
                                                            • > Так оно что там, флаги на запись и исполнение что ли на ходу правит?
                                                              >> call ___enable_execute_stack
                                                              Угумс.
                                                              Ответить
                                                              • А эта хуйня, которая флаги правит, не вызывает системную питушню, переходящую в режим идра? Эта питушня не тормозит?
                                                                Ответить
                                                                • > А эта хуйня, которая флаги правит, не вызывает системную питушню, переходящую в режим идра? Эта питушня не тормозит?
                                                                  1 раз на старте проги же достаточно вызвать. Чего она будет тормозить.
                                                                  Ответить
                                                                  • 1 раз вызвать на весь стек?
                                                                    Прощай, безопасность?
                                                                    Ёпт, такая сишка - только для питухов.
                                                                    Ответить
                                                                    • > 1 раз вызвать на весь стек?
                                                                      Ну а как еще. Не питушиться же со страничками постоянно. Один хуй 4-8 килобайт придется открыть на исполнение ради одного трамплина... Меньше странички же права никак не настроить.

                                                                      > Прощай, безопасность?
                                                                      Угу. Привет эксплойты ;) Если без исполняемого стека в линухе сейчас эксплойт запустить довольно сложно - работает рандомизация адреса стека и библиотек, и почти всегда прога крашится, вместо того, чтобы исполнить произвольный код. То здесь открытые ворота. Переполняй буфер по самый трамплин, и исполняй ;) Хотя царям питухов насрать. У них буфера в стеке никогда не переполняется, ибо они "знают свою платформу".

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

                                                                      P.S. Не, ну безусловно можно было сделать чуть безопаснее - запилить read-write-execute пул, в который складываются трамплины. Но т.к. в сишке нет деструкторов, это могло бы привести к утечкам на всяких там setjmp/longjmp.
                                                                      Ответить
                                                                      • >У них буфера в стеке никогда не переполняется, ибо они "знают свою платформу".
                                                                        Поэтому функции питушня, стек питушня и нахрен не упал и всё это питушня. Инлайн должен спасать от этих проблем, но гцц питух не хочет нормально инлайнить. Надо пропатчить питуха.


                                                                        У царей нет буферов на стеке, ибо стек питух.
                                                                        Ответить
                                                                        • > У царей нет буферов на стеке, ибо стек питух.
                                                                          А кучу цари не юзают, ибо медленная. Поэтому все переменные у царей глобальные.

                                                                          > Инлайн должен спасать от этих проблем
                                                                          Ага, превращая прогу в стометровое говно.
                                                                          Ответить
                                                                          • С чего ты взял, что куча медленна? Медленны питух-аллокаторы, а царь не юзает питух-аллокаторы.


                                                                            Поэтому регистры и куча.


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


                                                                            Реально инлайн не увиличивает длинну нормально написанного кода, а нааборот уменьшает. А если код питух - он итак будет 100метровый, хотя есть питухдинамиклибы, которые типа избавляют вас от этих проблем.
                                                                            Ответить
                                                                            • > Реально инлайн не увиличивает длинну нормально написанного кода, а нааборот уменьшает.

                                                                              Какие-то питухочудеса!
                                                                              Ответить
                                                                            • я конечно не спец. Но инлайн это вставка кода функции в место вызова.
                                                                              Как вставка кода может уменьшить объем этого самого кода. И с примером пожалуйста.
                                                                              Ответить
                                                                              • тогда, когда инлайновая функция вызывается ровно 1 раз - вместо накладных расходов по вызову функции, у которой есть тело объемом X, в котором есть операции по обращению к стеку за аргументами + возврат значения обратно, подставится код объемом Y < X, в котором всех этих расходов нет, а нужные аргументы уже разложены по регистрам
                                                                                Ответить
                                                                                • А насколько это Y меньше X. Имеет ли смысл экономить ?
                                                                                  Ответить
                                                                                  • прежде всего вляет физическое ограничение на место под бинарник - т.е. парит ли плюс минус мегабайт exe файла
                                                                                    и в последнюю очередь - убертюнинг перформанса, когда в питушиный кеш питушиных инструкций может перестать влезать и перформанс упадет, как будто его писал анскильный питух

                                                                                    во всех остальных случаях мелкие функции проще объявлять инлайновыми (причем, в c++ они с большой вероятностью будут такими изза шаблонности или описания прямо в теле класса)

                                                                                    в любом случае компилятор при включенной оптимизации сам разберется, что инлайнить, что нет - независимо от наших рекомендаций
                                                                                    Ответить
                                                                                    • >в любом случае компилятор при включенной оптимизации сам разберется, что инлайнить, что нет - независимо от наших рекомендаций
                                                                                      Даже понтовый гцц тот ещё питух и иногда фейлит с инлайном, поэтому проще написать инлайн и быть уверенным в нормальной порятнке, чем гадать.
                                                                                      Ответить
                                                                                  • Экономят не место, а l1i.
                                                                                    Ответить
                                                                                  • И ещё, у инлайн функции в сишке нет тела. Т.е. ты можешь создавать функцию на каждый чих, функцию для вызова пару раз в программе и т.п. И когда не будет раздуваться.
                                                                                    Ответить
                                                                              • > Как вставка кода может уменьшить объем этого самого кода

                                                                                Простые функции вроде max при инлайне займут меньше инструкций, т.к. при вызове функций обычно нужно сохранять состояния нескольких регистров на стеке.
                                                                                Ответить
                                                                              • Смотри - у тебя идёт серьёзные вычисления - ты юзаешь почти все регистры и бам - тебе надо вызвать функцию. Тебе надо задампить все регистры, либо зафигачить их в стек в зависимости от call abi. Потом ещё в зависимости от тела твоей функции - тебе надо дампить регистры даже при стековом вызове. Потом раздампиливать регистры, возвращать результат - писать 2 лишних иструкции калл и рет + занимать место в l1i на адрес функции.


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


                                                                                Потом не забывай, что обычно инлайн функции маленькие и их тело примерно равно оверхеду на их вызов.


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


                                                                                В конечном итоге инлайн проиграет только в тех случаях, когда у тебя будут поочерёдно вызваться 100разных функции, в которые будут инлайнится 1 большая инлайн функция и это всё будет юзаться в цикле и 100разных функции с вызовом большой "инлайн" функции влезут в l1i, а с инлайном уже нет. Такое маловероятно.


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

                                                                          Нет, стек не питух, это буфер - питух.
                                                                          Ответить
                                                                          • Какразтакистекпитух, ибо он ненужен. Да на 32битном питухе без него не обойтись, но вот на 64битном питухе он не упал, но 32битный питух тоже не упал - поэтому стек не упал. А все 32битные питухи подлежат уничтожению.


                                                                            Я сейчас говорю только про х86.
                                                                            Ответить
                                                                            • Нет, это буфер - питух, а стек - не питух, потому что питухи на стеке питуховыделяются через один питуходекременн.
                                                                              Ответить
                                                                              • Дак в куче так же, с нормальным аллокатором. Зачем нуежн стек? Это тысячи проблем, тормазов и иной питушни. Он жрёт и занимает кеш, как питух - причем неподконтрольно. Он сжирает целых 2регистра, которые можно использовать получше.

                                                                                Т.е. запилить на них реальнонормальный софтварный стековый аллоктор, который нежрёт регистры и моя идея с заменой в ваших плюсах ГЦ(всякие виды автоптров, деструкторы и прочее) на софтварный стек - реализовывалась ещё проще.


                                                                                На нормальной ОС и 64битном питухе стек может быть безразмерный с постоянными адресами.


                                                                                Благо от этой питушни с попами ушли, что хоть радует.
                                                                                Ответить
                                                                                • Так где экономия регистра - что тебе нужен регистор для указателя на вершину стека, что тебе нужен регистор для указателя на место, где хранятся параметры.
                                                                                  Освободить регистор можно только если поступить по-фортрановски - все локальные переменные всех функций имеют фиксированные адреса. Никакой рекурсии при этом уже быть не может.
                                                                                  Ответить
                                                                                  • Дак в том и суть - мне не нужен никакой регистр - регистр просто для оптимизации, а на самом деле профита от него нет. Никакие параметры тоже не упёрлись. 2регистра.


                                                                                    А рекурсию можно запилить и так, да и она нахрен не упёрлась
                                                                                    Ответить
                                                                                    • Чтобы запилить рекурсия, надо эмулировать стек. От чего ушли, к тому пришли.
                                                                                      Ответить
                                                                                      • Какую рекурсию - поясни. Для рекурсии можно юзать любой региср и он не будет зарезервирован. Рекурсию проще превратить в цикл, а аргументы в ргестры. Ничего не сохранять, а юзать те же регистры, как аргументы.


                                                                                        Нужен тебе стек - вводи ключевое слово recursive и конпелятор будет юзать софтварный стек, который может быть бесконечен, если бесконечна твоя оператива. Это даст возможность тебе вызвать рекурсию миллиарды раз.


                                                                                        А там, где функция не рекурсивная - там конпелятор может юзать на 2 регистра больше.
                                                                                        Ответить
                                                                                        • > Какую рекурсию - поясни
                                                                                          Например, для обхода в глубину. Да, можно руками эмулировать FIFO-контейнер, ну и ради чего?
                                                                                          Переделать ветвящуюся рекурсию в цикл - только если вручную хранить цепочку данных о вызовах функций, то есть опять же - руками эмулировать стек.

                                                                                          > Нужен тебе стек - вводи ключевое слово recursive

                                                                                          Это питушня, компилятор должен уметь сам определять, рекурсивна ли функция.
                                                                                          Ответить
                                                                                          • Дак в чём проблема? Юзай стек только для рекурсивных функций, но не юзай его вообще.


                                                                                            >Это питушня, компилятор должен уметь сам определять, рекурсивна ли функция.
                                                                                            Твой паскаль нихрена не умеет определять - ты же не ноешь? Пусть определяет и юзает там стек, но в остальных стек пусть не юзает, а регистры юзает, но не под стек.
                                                                                            Ответить
                                                                                            • > Дак в чём проблема? Юзай стек только для рекурсивных функций, но не юзай его вообще.

                                                                                              Ручками его умулировать?
                                                                                              А ещё при статическом размещении локальных переменных функций эти самые переменные могут быть раскиданы по всей оперативе, в отличие от стека, где все они аккуратно собраны в одном месте.
                                                                                              И прыгать по оперативе - это просто пиздец насколько дороже, чем лишний раз переложить из регистра в регистр.

                                                                                              > Твой паскаль нихрена не умеет определять - ты же не ноешь?

                                                                                              В моём Паскале реализация рекурсивной функции не отличается от реализации просто-функции, потому что и те, и те просто используют стек. Поэтому ему не нужен определятор рекурсии.
                                                                                              Ответить
                                                                                              • >Ручками его умулировать?
                                                                                                Конпелятором, только у тебя будет специальный стек для каждой функции, который может быть бесконечен.

                                                                                                >А ещё при статическом размещении локальных переменных функций эти самые переменные могут быть раскиданы по всей оперативе, в отличие от стека, где все они аккуратно собраны в одном месте.
                                                                                                В регистрах, в регистрах. Инициализаторы и константы с кодом в l1i.

                                                                                                Какраз-таки наоборот. Статик укомпонован и выравнен нормально. Всё рядышком - всё отлично. Прыгать по аперативе дёшево, если ты юзаешь страницы нормально( а в stl ты не юзаешь страницы нормально и у тебя ОМГПИТУХ оверхед, и это последние, о чём тебе надо думать).


                                                                                                В функции всё хранится только в регистрах, никаких стеков/куч и прочего. Никакой статической памяти и прочего - только регистры.


                                                                                                >В моём Паскале реализация рекурсивной функции не отличается от реализации просто-функции, потому что и те, и те просто используют стек. Поэтому ему не нужен определятор рекурсии.
                                                                                                Поэтому он тормазит как питух. Стек устарел ещё лет 15назад.



                                                                                                Поэтому повторю ещё раз. В функция для переменных юзаются ТОЛЬКО регистры. Работа с кучей через указатели(адреса), как и раньше.

                                                                                                Функции вызываются, а аргументы передаются через регистры, либо функция инлайнится.


                                                                                                Если функция рекурсивная, то конпелятор юзает кучу, как стек, а указатели хранит в стековых регистрах.


                                                                                                Здравствуй перфоманс и ещё 2регистра.
                                                                                                Ответить
                                                                                                • > В регистрах, в регистрах. Инициализаторы и константы с кодом в l1i.

                                                                                                  А если регистров не хватит?
                                                                                                  l1i - это что? Кэш 1го уровня? Так верхушка стека и так в нём.

                                                                                                  > Статик укомпонован и выравнен нормально.

                                                                                                  У тебя 100500 функций, их статики, вместе взятые, очевидно, не могут влезать в одну страницу памяти. При таком подходе ниего не стоит обратиться к статикам, находящимся слишком далеко друг от друга. Не вижу, почему это должно быть быстрее стека.

                                                                                                  > Поэтому он тормазит как питух. Стек устарел ещё лет 15назад.

                                                                                                  Все тормозят, как питухи, потому что все используют стек, кроме древнего фортрана?

                                                                                                  > Функции вызываются, а аргументы передаются через регистры, либо функция инлайнится.

                                                                                                  С параметрами понятно, стек вызовов куда девать?
                                                                                                  Ответить
                                                                                                  • >А если регистров не хватит?
                                                                                                    На нормальный код хватит.

                                                                                                    >l1i - это что? Кэш 1го уровня? Так верхушка стека и так в нём.
                                                                                                    Это кеш данных, в который процессор читает твой код. Верхушка твоего питуха не в нём, ибо в отличии от префетча кода процессор не умеет префетчить стек, ибо это невозможно.

                                                                                                    >У тебя 100500 функций, их статики, вместе взятые, очевидно, не могут влезать в одну страницу памяти. При таком подходе ниего не стоит обратиться к статикам, находящимся слишком далеко друг от друга. Не вижу, почему это должно быть быстрее стека.
                                                                                                    Какие статики - ты что несёшь? Ты несёшь тотальную херню с какими-то статиками. Константы, которые ты присваиваешь внутри функции находятся не в статиках, а вместе с кодом.


                                                                                                    >Все тормозят, как питухи, потому что все используют стек, кроме древнего фортрана?
                                                                                                    gcc для amd64 не использует стек вообще в 95% кода. Использует только для дампа регистров, ну и адресов возврата для твоих функций.

                                                                                                    >С параметрами понятно, стек вызовов куда девать?
                                                                                                    Кому упёрся твой стек вызовов. Метки и джампа, либо адрес возврата в регистр.
                                                                                                    Ответить
                                                                                                    • > На нормальный код хватит.

                                                                                                      Не засчитываю.

                                                                                                      > Константы, которые ты присваиваешь внутри функции находятся не в статиках, а вместе с кодом.

                                                                                                      А локальные переменные куда? Тоже вместе с кодом?
                                                                                                      Я знаю, что мутабельное говно - для питухов, но это только на уровне исходника, а на уровне машинного кода мутабельность это нормально.
                                                                                                      Переменные рядом с кодом - это открыть код на запись?

                                                                                                      > Метки и джампа

                                                                                                      Открыть код на запись?

                                                                                                      > либо адрес возврата в регистр.

                                                                                                      Ну и где твоя экономия регистров?
                                                                                                      Ответить
                                                                                                      • >Не засчитываю.
                                                                                                        Собери нормальный код на amd64 и погляди, сколько там юзается стек.


                                                                                                        >А локальные переменные куда? Тоже вместе с кодом?
                                                                                                        Локальная переменная - это регистр.

                                                                                                        >Тоже вместе с кодом?
                                                                                                        Константы, которые ты передаёшь вместе с инструкциями - да, остальное уже компилспецифик и само появяляется в регистрах в процессе вычислений.

                                                                                                        >Я знаю, что мутабельное говно - для питухов, но это только на уровне исходника, а на уровне машинного кода мутабельность это нормально.
                                                                                                        Переменные рядом с кодом - это открыть код на запись?
                                                                                                        Да что ты несёшь - переменные это и есть регистры. Ну не может у тебя быть одновременно овер 10 активных переменных. Остальное - это твоя куча.


                                                                                                        >Открыть код на запись?
                                                                                                        Да нет никакой записи - все вызовы функций компилспецифик. Просто вместо калла юзает jmp, а после ты можешь взять адрес следующей за джампом инструкции и передать её в регистре. Можно запилить како-нибудь шаманизм с ripом.


                                                                                                        >Ну и где твоя экономия регистров?
                                                                                                        Да вот же она. Минимум 1регистр остаётся. Вне функции остаётся ещё 1регистр. Этот регистр можно юзать как *this - т.е. биндить на функцию данные. Т.е. связывать её локальный контекст с данными и получится аля ваши классы и перегрузка, только ещё понтовей. int i; void f(a, b); bind(v::a, i); и теперь аргумент связан с твоей локальной а и ты можешь юзать f(1); - 1 передаётся сам, причем по ссылке.

                                                                                                        Это позволит делай просто инлайн анролл, да тысячи фич, но кому это нахрен надо - у нас есть стек.
                                                                                                        Ответить
                                                                                                        • > Ну не может у тебя быть одновременно овер 10 активных переменных.

                                                                                                          А если их всё-таки больше 10, то что?

                                                                                                          > а после ты можешь взять адрес следующей за джампом инструкции и передать её в регистре.

                                                                                                          И занять регистр. И что делать, если 10 вложенных функций вызываются? Я не спрашиваю, питушня 10 вложенных функций или нет, я спрашиваю, что делать, если всё-таки это произошло. Использовать стек?
                                                                                                          Ответить
                                                                                                          • >А если их всё-таки больше 10, то что?
                                                                                                            У тебя 4-5 штук есть ещё, а если уж и их нехватит - есть всякие фпу регистры, а уж если их не хватит, то дампь в кучу.

                                                                                                            >И занять регистр. И что делать, если 10 вложенных функций вызываются? Я не спрашиваю, питушня 10 вложенных функций или нет, я спрашиваю, что делать, если всё-таки это произошло. Использовать стек?
                                                                                                            ОДИН, а не два. И только только внутри функции, который можно задампить в кучу.

                                                                                                            Да, ты можешь юзать стек. Я уже говорил про это. У тебя в регистре есть ещё местро на 1адрес, но юзай стек.


                                                                                                            Суть в том, что вменяемая архиктура, вменяемое устройство СУЩЕСТВУЕТ ТОЛЬКО ДЛЯ МИРА НОРМАЛЬНОГО КОДА. А для мира питухов - есть х86 говно и С++.


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


                                                                                                            Как-то так.
                                                                                                            Ответить
                                                                                              • Определятор рекурсии не нужен нигде, потому что рекурсия бывает и косвенной. Например, функция A вызывает функцию B, функция B вызывает функцию C, а функция C вызывает функцию A, причём все функции могут быть в разных модулях. Как прикажете такую рекурсию определять?

                                                                                                Либо нужно генерировать код, совместимый с возможной рекурсией, либо реализовывать свой Фортран с яйцами и курочками, в котором даже косвенная рекурсия запрещена.
                                                                                                Ответить
                                                                                                • > Как прикажете такую рекурсию определять?

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


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


                                                                                                  Из-за таких питухов как вы, со своими либами и проприетарщиной и придумывают всякие кастыли типа лто.


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


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


                                                                                                      Чуть подоптимизировать конпеляторы, выпилить лишние питух-оптимизации, писать нормальный код и можно миллионны строк мержить.
                                                                                                      Ответить
                                                                                                      • накой хуй мне на 8 ядерном цпу собирать однопоточно, когда я могу это сделать в 8 раз быстрее?
                                                                                                        Ответить
                                                                                                        • Наверное потому, что нормально написанный код и специально заточеный под мерж конпелятор будет собирать так же на одном ведре? И это сикод, а не питшня плюсовая.
                                                                                                          Ответить
                                                • > Итого: на x86 gcc использует регистр ecx для передачи во вложенную функцию адреса блока локальных переменных.

                                                  Итого : указатель на блок таки передаётся, а наше using его не передаёт, то есть код таки говно.
                                                  Ответить
                                                  • > на x86 gcc использует регистр ecx для передачи во вложенную функцию адреса блока локальных переменных.
                                                    Только если вложенная функция вызывается из блока, в котором она описана. Если передать по указателю - генерится другой код.

                                                    Там в стеке генерится трамплин с mov ecx, контекст; jmp вложенная функция. Вот адрес этого трамплина и передается туда, где его будут использовать.
                                                    Ответить
                                                    • Так трамплин-то кто генерирует?
                                                      Его внешяя функция генерирует до вызова using и этот using какого-то хрена должен знать, что ecx надо сохранить до вызова калобяки?
                                                      Ответить
                                                      • > Так трамплин-то кто генерирует?
                                                        Функция, внутри которой описана локальная функция в тот момент, когда она хочет куда-то передать указатель на локальную функцию.

                                                        > должен знать, что ecx надо сохранить до вызова калобяки
                                                        Согласно cdecl: Registers EAX, ECX, and EDX are caller-saved, and the rest are callee-saved, поэтому всем насрать.
                                                        Ответить
                                                        • Хорошо, а если будет несколько локальных функций, вложенных друг в друга, то что? Сохранять трамплины на стек и в ecx писать адрес последнего трамплина?
                                                          Ответить
                                                          • Бляяяяя до меня дошло, динамическая кококодогенерация тут по сути. Ну и питушня же!
                                                            Ответить
                                                            • >>call ___enable_execute_stack
                                                              > динамическая кококодогенерация тут по сути
                                                              Надо попробовать написать какую-нибудь высокопроизводительную питушню с генерацией кода прямо в стеке.
                                                              Ответить
                                                              • Ну лалки дошли до идей первого вброса.
                                                                Ответить
                                                                • Поздравляю, ты вылечил TarasB и bormand :D
                                                                  Ответить
                                                                • До идеи, что трамплин (или замыкание или что там) чудом уцелел на стеке, мы и так дошли.
                                                                  Ответить
                          • > Питух, иди читай с99. Это часть логики.
                            ISO/EIC 9899:1999 6.7.4. Function specifiers. Пункт пятый.
                            Making a function an inline function suggests that calls to the function be as fast as possible (118). The extent to which such suggestions are effective is implementation-defined (119).

                            118) By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline substitution’’. Inline substitution is not textual substitution, nor does it create a new function. Therefore, for example, the expansion of a macro used within the body of the function uses the definition it had at the point the function body appears, and not where the function is called; and
                            identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a single address, regardless of the number of inline definitions that occur in addition to the external definition.

                            119) For example, an implementation might never perform inline substitution, or might only perform inline substitutions to calls in the scope of an inline
                            declaration.
                            Ответить
                            • И? Тут написанно предположение. Есть инлайн - у него есть свойство - инлайнится всегда, а если не может - не вызывается, ибо кода нет. Это свойство описанно стандартом и я могу его юзать как свойства статиклокальных переменных и т.п.


                              Что ты хотел своей пастой показать - я не понял.
                              Ответить
                              • > The extent to which such suggestions are effective is implementation-defined
                                Вот это например хотел показать. Что в стандарте нигде не сказано, что компилятор что-то обязан инлайнить. Т.е. в твоем случае это надо смотреть в мане от gcc, и никогда не говорить, что "обязан по стандарту" ;)
                                Ответить
                                • Он не обязан инлайнить, но он обязан не гинерить код. Поэтому код либо инлайнится - либо не собирается. А неинлайнит конпелятор по понятным причинам и это писанно в мане, аля аллока и прочая байда связанная со стеком.
                                  Ответить
                                  • > Он не обязан инлайнить, но он обязан не гинерить код.
                                    Ну да. Сам по себе С99 компилятор код для инлайн функции не сгенерит, согласен. Можно заставить его сгенерить такой код, но это уже не автоматика.
                                    Ответить
                  • #include <stdio.h>
                     
                    typedef void(* file_handler_t)(FILE* fileHandle);
                     
                    inline void using_file(FILE* fileHandle, file_handler_t fileHandler/*a*/) {
                        /*if(!fileHandle)
                            return;*/
                        fileHandler(fileHandle);
                    //     fclose(fileHandle);
                    }
                     
                    int main(void) {
                        int tarasB={0};
                        using_file(fopen("myfile.txt","w"),
                            ({void body(FILE* fileHandle) {
                                /*пишем в fileHandle;*/
                                ++tarasB;
                            }; body;})//b    
                        );
                        ++tarasB;
                        
                        fprintf(stdout, "%i", tarasB);
                        return 0;
                    }


                    .file	"main.c"
                    	.text
                    	.p2align 4,,15
                    	.type	body.2266, @function
                    body.2266:
                    .LFB13:
                    	.cfi_startproc
                    	addl	$1, (%r10)
                    	ret
                    	.cfi_endproc
                    .LFE13:
                    	.size	body.2266, .-body.2266
                    	.section	.rodata.str1.1,"aMS",@progbits,1
                    .LC0:
                    	.string	"w"
                    .LC1:
                    	.string	"myfile.txt"
                    .LC2:
                    	.string	"%i"
                    	.section	.text.startup,"ax",@progbits
                    	.p2align 4,,15
                    	.globl	main
                    	.type	main, @function
                    main:
                    .LFB12:
                    	.cfi_startproc
                    	pushq	%rbx
                    	.cfi_def_cfa_offset 16
                    	.cfi_offset 3, -16
                    	movl	$-17599, %eax
                    	movl	$-17847, %edx
                    	subq	$32, %rsp
                    	.cfi_def_cfa_offset 48
                    	movl	$.LC0, %esi
                    	movl	$.LC1, %edi
                    	movw	%ax, 4(%rsp)
                    	leaq	4(%rsp), %rbx
                    	movl	$body.2266, %eax
                    	movw	%dx, 10(%rsp)
                    	movl	%eax, 6(%rsp)
                    	movq	%rsp, 12(%rsp)
                    	movl	$-1864106167, 20(%rsp)
                    	movl	$0, (%rsp)
                    	call	fopen
                    	movq	%rax, %rdi
                    	call	*%rbx
                    	movl	(%rsp), %eax
                    	movl	$.LC2, %esi
                    	movq	stdout(%rip), %rdi
                    	leal	1(%rax), %edx
                    	xorl	%eax, %eax
                    	movl	%edx, (%rsp)
                    	call	fprintf
                    	addq	$32, %rsp
                    	.cfi_def_cfa_offset 16
                    	xorl	%eax, %eax
                    	popq	%rbx
                    	.cfi_def_cfa_offset 8
                    	ret
                    	.cfi_endproc
                    .LFE12:
                    	.size	main, .-main
                    	.ident	"GCC: (Gentoo 4.9.0_pre9999) 4.9.0-pre9999 20130614 (experimental) commit 6feb84280229dcfe54d8369df1722407e43a64a9"
                    	.section	.note.GNU-stack,"x",@progbits


                    Тараса он тут какбэ формально не заинлайнил, но по факту - это инлайн. Поэксперементировать можно, авось можно выпилить кал, но мне пока лениво.
                    Ответить
    • си с гццизмами может все, но не всегда стоит это делать...
      Ответить
      • Сейчас придет Царь, и наглядно объяснит тебе, почему гццизмы это хорошо, нужно и полезно.
        Ответить
        • уже боюсь
          Ответить
          • Ну, в принципе, могу поработать его заместителем just for lulz ;)

            Любой вменяемый компилятор умеет гццизмы. А если он их не умеет, то этот компилятор - бесполезное никому не нужное говно, и юзать его я не буду.
            Ответить
            • в каждой фразе Царя должно быть слово однокоренное с питушок, иначе это не Царь
              Ответить
              • Ну, в принципе, ради вас питушков, могу поработать его заместителем just for lulz ;)

                Разве ты не знал, питушок, что любой вменяемый компилятор умеет гццизмы. А если этот питуханский питухокомпилятор их не умеет - то его писали анскильные питухи, и это бесполезный, никому не нужный куриныйпитушиный помёт, который юзать будут только питушки-анскилябры, но не я.
                Ответить
                • а еще коНпЕлятор
                  Ответить
                  • Как ты смеешь указывать на ошибки Царю Сишных Конпеляторов, ничтожный петушок?
                    Ответить
                    • Кстати, питушок, а ты зря ржешь - ведь вменяемых конпеляторов неумеющих гццизмы нет.
                      Ответить
                    • И да, кстати, ты же спрашивал зачем нужно то извращение - вот зачем.
                      Ответить
    • Я даже тебя похвалю - всё по моим заветам. Пацаны так и пишут код - зафигачиваешься хедлер и имя и фичачется в пулл. Потом пул выполняется.


      Но этом в овер 50% случаях не надо, ибо открытие и закрытие файлов - это питушня гуйявская.


      Тарас же геймдев питушок? Вот юзай пулы с хедлерами.
      Ответить
      • Я юзаю std::ofstream.
        Ответить
        • Который работает раз в 20тормазнее моео варианта? Тыж геймдевпитух? Ты клал на перфоманс?


          Хотя тыж маздайский питушок, у тебя там хоть fstat() есть? Или ты как питушок чтобы узнать длинну файла его читаешь?


          Чего люди не придумают, а лишь только потому, что их питух ОС нихрена не может.


          Я кажется понимаю откуда у тебя знания по конпеляторам из msvs2003, ибо такую бездарную питушню может нести только адепт питухконпелятора.
          Ответить
          • > Который работает раз в 20тормазнее моео варианта? Тыж геймдевпитух? Ты клал на перфоманс?

            Я полностью клал на перфоманс операции, выполняющейся раз в несколько минут и длящейся меньше десятой доли секунды :D
            Ответить
            • Дак так же тормазит у тебя всё. Т.е. ты юзаешь фуфло, которые в 20раз тормазнее, для которого надо в 10раз больше кода писать и оправдываешь это тем, что ты клал на всё? Ок, понятно.
              Ответить
              • > Дак так же тормазит у тебя всё.

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

                > Т.е. ты юзаешь фуфло, которые в 20раз тормазнее, для которого надо в 10раз больше кода писать и оправдываешь это тем, что ты клал на всё?
                > в 10раз больше кода

                Пиздишь.
                Ответить
                • Да, да. Ну давай запилем батл - выкатывай в говнокоде задачку. Тарас ака питух вс суперхаккиллер ака царь. Только вменяемую, с референсным кодом.
                  Ответить
                  • Давай, запили физику твёрдых выпуклых тел в 2д.
                    Ответить
                    • да он даже не знает что такое тангенс
                      как он будет столкновения определять?
                      Ответить
                      • Не знаю. А мне с бокс2Д сравниться бы интересно.
                        У меня как бы есть бонус - отсутствие трения и да-да, фиксированная запятая. У бокс2Д есть бонус - это скилл авторов.
                        Ответить
                    • Выкатывай референсный код, всё по правилам - вменяемое объяснение задачи с примерами - я тебе запилю. Потом честно сравним решения.
                      Ответить
                      • Задача - сделать выглядящую правдоподобно систему с твёрдыми телами, которые сталкиваются друг с другом.
                        Как тут: https://play.google.com/store/apps/details?id=tarasB.FluidArkanoid.free
                        это если у тебя есть ведроидная мобила
                        Ответить
                        • Я похож на питуха, которому нужна ведроиднай мобила и игрулечка на ней?


                          Выкатывай референсный код, описание задачи, критирии "правильности"(правдоподобности). Твой скрин выглядит как питушня, а правдоподобности я там не вижу.


                          Пилить хрен знает что из-за кукареканья питушка я не собираюсь.
                          Ответить
                          • > Я похож на питуха?

                            Да.
                            Такой формулировки нормальному человек достаточно, чтобы понять, что от него хотят. Ну, если только он не питух анскильный, как ты.
                            Ответить
                            • Реально? Т.е. примеров, референсного кода, каких-то критериев правдоподобности я не увижу? Питух он и есть питух.
                              Ответить
                              • Да, не увидишь.
                                Того, что я сказал, достаточно, чтобы понять задачу. Примеры и код нужны только питухам.
                                Ответить
                            • Здесь он прав. Ты ему в конце скажешь неправдоподобно и работу он провалит чтобы он не делал. Или у тебя тоже повадки царя: "Сказал не правдоподобно, значит не правдоподобно!"
                              Ответить
                              • Какие нахрен могут быть критерии правдоподобности физики, кроме чисто на глаз?
                                Ответить
                                • > Какие нахрен могут быть критерии правдоподобности физики

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


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


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


                                      Так же и тут - ты пишешь портянку, которой показываешь что ты от меня хочешь.


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

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

                                        задачу на лоре тебе дали не самую простую - численные методы это не программа 1 курса, но они не думали, что ты настолько анскиллен

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

                                        ты же считаешь себя гением
                                        первокурсники себя гениями не считают, но такие задачи щёлкают, как орехи
                                        люди не заканчивают школу (редкий случай, да), потому что считают, что всё что в ней дадут - они освоят самостоятельно за полчаса - такая же логика относится и к тем, кто не заканчивает институтов (такое чаще бывает)

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

                                        итак, анскильный тарас решил такую задачу, причем постарался сделать это оптимально для своей платформы как умел
                                        никто за тебя её решать не собирается, давать какой то референсный код - пока что тебе засчитается сам факт, что ты получишь примерно правильный ответ

                                        а потом тарас тебе расскажет где конкретно узкие места и почему ему понадобился фиксед, ок?
                                        Ответить
                                        • > я же тебе тарасовскую программу упрощаю в такую элементарную задачу

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

                                          > а потом тарас тебе расскажет где конкретно узкие места

                                          Оно кстати вовсе не в расталкивании тел у меня было, а в определении точки контакта двух выпуклых многоугольников.
                                          Ответить
                                        • показать все, что скрытоТ.е. питушок слился и ты тоже. Так и запишем. Питушки гордятся своим умением решать бесполезные студзадачи.
                                          Ответить
                                          • Можно, пожалуйста, увидеть решение про среднее арифметическое джвух интов?
                                            Ответить
                                            • Кинь ссылку на тему про среднее арифметическое двух интов.
                                              Ответить
                                              • >на тему про среднее арифметическое
                                                Не надо.
                                                1. Я хочу увидеть незамутненное решение от гуру.
                                                2. ЕМНИП там не было верного решения
                                                Ответить
                                                • А я и не знаю уже даже, какое верное, у меня есть надёжное решение для двух уинтов, но оно тормозное.
                                                  Ответить
                                                  • >А я и не знаю уже даже, какое верное
                                                    Я тоже :)
                                                    Может скиллед нам подскажет?
                                                    Ответить
                                          • т.е. ты банально не можешь?
                                            и ты теперь этим гордишься?

                                            ты в бильярд играл когда-нибудь?
                                            задача интуитивна

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

                        У тебя есть шанс проявить себя.
                        Ответить
                        • Какие- же это школьные задачи. Я даже в школе на такой дет. сад времени не тратил.
                          Ответить
                          • Давай решение. Если это так просто.
                            Язык - сишка, кресты, шарп, жаба. Для определенности.
                            Ответить
                            • кол-во переменных как-то меняется?
                              Ответить
                              • Нет. На вход подается _два_ числа. На выходе их среднее.
                                Нужно написать функцию, с сигнатурой:
                                int avg(int a,int b).
                                intы - знаковые
                                Ответить
                                • Ой жешь, точно. переполнение. :)
                                  Ответить
                                  • Спасибо. Вы нам не подходите.
                                    Ответить
                                    • Да, пожалуйста. Хотя я думаю вы не очень-то красиво поступаете. СрачСпор то был о знании C++, а задача об алгоритмизации. ;)
                                      Ответить
                          • вас в школе научили избегать целочисленного переполнения?
                            Ответить
                            • давайте _все_ заинтересованные стороны выложат свои варианты решения, а потом уже будем комментировать.
                              Ответить
                              • я его сейчас допишу и протестирую, но выложу когда скажут, что можно
                                Ответить
                                • Пусть сначала superhackkiller1997 покажет нам скиллед-решение на сишке.
                                  Ну и задача должна легко масштабироваться на long и прочие целые.
                                  Ответить
                                  • С пишатскийми интами? Нахрен они мне. signed для питух, и я уже говорил это.
                                    inline uint64_t t(uint64_t a, uint64_t b) {  
                                      return (a >> 1) + (b >> 1) + ((a & 1) | (b & 1));
                                    }


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

                                      > ((a & 1) | (b & 1))
                                      лишняя операция
                                      Ответить
                                    • >С пишатскийми интами?
                                      http://ideone.com/iYen1I
                                      Ты - гавно!
                                      t(12,13)=13

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

                                      Помню делал такое на шарпе, но у меня некрасиво получилось.
                                      Ответить
                                      • Я только в столбик умею.
                                        Ответить
                                        • Да, вот я тоже в столбик делал.
                                          Мне даже понравилось. Думаю все таки возьмусь за плюсы. Это весело ;)
                                          Ответить
                                      • >не используя операции умножения и деления.

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

                                        Умножение, есть прибавление множимого со сдвигом (есть в множителе 1 или нет), ок?

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

                                        Второй способ - обычное деление в столбик для двоичной системы. Я его люблю больше. Сдвигаем,если больше, отнимаем и пишем 1 в результат, иначе пишем ноль, опять сдвигаем. итд...
                                        С корнями чуть сложнее.
                                        Ответить
                                        • Умножение на магическое число - только если делишь на константу.
                                          Ответить
                                        • Оу, а вы уже закончили университет?
                                          Ответить
                                          • >вы уже закончили университет
                                            Давно. Кстати тех способов что там учили я так и не понял. Объясняли их как-то через жопу, отличались всего-лишь тем что сдвигать в какую сторону.

                                            >только если делишь на константу.
                                            Я указал это.

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

                                            Ну то есть по 32/64 бита за раз.
                                            Ответить
                                            • return (a & b) + ((a ^ b) >> 1);

                                              Этот код неправильно сработает на числах 12 и 13 же.
                                              Вариант кулцхакера лучше в этом.
                                              Ответить
                                              • >Этот код неправильно сработает на числах 12 и 13 же.
                                                Wut? Вы вообще тестировали?
                                                http://ideone.com/gGOuF8

                                                >Вариант кулцхакера лучше в этом.
                                                Он хуже. Во всем.
                                                Ответить
                                                • Ну вот смотрите:
                                                  12 - 1100
                                                  13 - 1101
                                                  Потом идет xor и в итоге 0001
                                                  Далее сдвиг, в итоге 0.
                                                  И о прибавляется к 12. В итоге 12, а должно быть 13.
                                                  Ответить
                                                  • >а должно быть 13.
                                                    То есть сишное целочисленное деление тоже неправильное работает, потому что округляет вниз?

                                                    25/2, должно быть 13?

                                                    Хм, каникулы?
                                                    Ответить
                                                    • Ну меня учили, что считать среднее арифметическое нужно с округлением, и если дробная часть больше либо равно 0.5 то округление должно быть в большую сторону.
                                                      Ну если вы округляли всегда в меньшую, то тогда вопросов нет.
                                                      Ответить
                                                      • Бляяяя а по контексту не очевидно, что нужно, а то, что сишка делает такое округление что не знал?
                                                        Ответить
                                                        • И не только сишка. И шарп, даже паскаль.
                                                          Но задачу нужно решать не в направлении того, как работают какие-то структуры яп'а.
                                                          :)

                                                          Причем в шарпе есть исправления для таких округлений.
                                                          Ответить
                                                  • Бля
                                                    Ответить
                                              • Разве?
                                                Ответить
                                              • >Вариант кулцхакера
                                                Полагаю это вариант в интернете, по запросу "найти среднее двух чисел без регистрации и переполнения".
                                                Ответить
                                                • А я давно уже взял за правило, что все, кто срутся, просто гуглят. :3
                                                  Ответить
                                                  • >что все, кто срутся, просто гуглят
                                                    Так там в выдаче неправильные говноспособы.
                                                    И ответы либо кепа, либо чувак, используй jquery LINQ.

                                                    В том-то и прикол, что какую-то справочную инфу, какой класс, метод, реверс строки итп - просто нагуглить.
                                                    А такую задачку - хер. В выдаче гугла один мусор.
                                                    Ответить
                                                    • Блин интересная задача, попробую на шарпе побайтоебить и подумать, как сделать супер-пупер хакастайл. :)

                                                      Даже наверное попробую с переменным числом аргументов.
                                                      Ответить
                                                    • > А такую задачку - хер. В выдаче гугла один мусор.
                                                      Вот, пожалуйста, третья ссылка по запросу "найти среднее двух чисел без регистрации и переполнения": http://forum.sources.ru/index.php?showtopic=312681&view=showall
                                                      Ответить
                                                      • >http://forum.sources.ru/index.php?showtopic=312681&view=showall
                                                        Охереть. Годно.
                                                        Я просто на англицком гуглил - ерунда сплошная.
                                                        А вот искомая проблема. Как красиво провести коррекцию?
                                                        signed avg(signed x, signed y)
                                                        {
                                                          signed tmp;
                                                         
                                                          if ((x^y) < 0) tmp = (x + y) >> 1;
                                                           else tmp = x + ((y - x) >> 1);
                                                         
                                                          return tmp + (tmp<0 && (x^y)&1);
                                                        }


                                                        http://www.google.com/search?q=average+of+two+numbers
                                                        Ответить
                                                        • return (x&y) + ((x^y) >> 1); ко-ко-ко питушок, макстер копипасты. На англ он гуглил.
                                                          Ответить
                                                          • Ты давай, решай поставленную задачу, сука.
                                                            >> (x&y) + ((x^y) >> 1)
                                                            Это классика, блядь. Это знать надо, если ты мнишь себя хукиром.

                                                            Разность, без переполнений.
                                                            Ответить
                                                            • У меня нет никакого переполнения питух. Скопипастил питух, даже не понимая как это работает? Питух.
                                                              Ответить
                                                              • Говорю, давай усредненную разность.
                                                                Вижу у тебя жопа болит, потому что твой способ оказался говном.
                                                                Ответить
                                                                • Ко-ко-ко.
                                                                  uint64_t av(uint64_t a, uint64_t b) { 
                                                                    return ((a + b) >> 1) + ((a & b) & (1ul << 63));
                                                                  }


                                                                  Держи ещё 1 вариант, питух. Вариации не тему.

                                                                  Питух.
                                                                  Ответить
                                                                  • > Держи ещё 1 вариант, питух.
                                                                    Не работает:
                                                                    uint64_t a = 0xFFFFFFFFFFFFFFFFull;
                                                                    printf("%llX %llX\n", a, av(a, a))
                                                                    Ответить
                                                                    • fprintf(stdout, "%lx, %lx\n", -1ul, av(-1ul, -1ul));
                                                                      ffffffffffffffff, ffffffffffffffff


                                                                      Проверяй свою питушню - у тебя питушарское переполнение. Он не может не работать.
                                                                      Ответить
                                                                  • >>> return ((a + b) >> 1) + ((a & b) & (1ul << 63));

                                                                    Я разность просил, идиотина.
                                                                    Ответить
                                                                • Кстати питух, твой код еле-еле на 10% быстрее моего первого варианта.
                                                                  Ответить
                                                                  • >быстрее моего первого варианта.
                                                                    Главное что он быстрее.
                                                                    К тому же твой первый вариант - говно.
                                                                    avg(2,3)=3
                                                                    Хоть бы он работал быстрее света, он НЕПРАВИЛЬНЫЙ.

                                                                    А теперь, пожалуйста, усредненную разность двух чисел.

                                                                    avgSub(100,50)=(100-50)/2=25.
                                                                    Ответить
                                                                    • Питух, я там перепутал and и or. Но сливай, сливайся питух. Там должен быть 1 когда 2нечётных, а не одно из них.
                                                                      Ответить
                                                                      • > я там перепутал and и or.
                                                                        Это неважно, потому твой способ тормозной, а ты уёбок и хуй.
                                                                        Покушал говнеца на ровном месте.

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

                                                                        Значит ты тупоносый лабась, который взял чужое и даже не разобрался.
                                                                        Ответить
                                                                        • Питух? Твой код еле-еле на 10% быстрее моего. Я вижу по твоему поведению, что ты взял, скопипасти и попал в лужу, как питух.


                                                                          Чужое? Т.е. я взял чужое, и специально перепутал? Ок. ТруЪ логика, пацантра - она даже не вызвает у меня улыбки - настолько правдоподобна.
                                                                          Ответить
                                                                          • > скопипасти и попал в лужу, как питух.
                                                                            > Т.е. я взял чужое, и специально перепутал?
                                                                            Поставленная задача:
                                                                            1. найти среднее арифметическое двух знаковых чисел не решена.
                                                                            2. найти усредненную разность двух чисел не решена.

                                                                            http://govnokod.ru/13183#comment181848
                                                                            Питушки юлят жопой, когда видят, что не могут осилить задачу.
                                                                            Ответить
                                                                            • >1. найти среднее арифметическое двух знаковых чисел не решена.
                                                                              Со знаками идёт нахрен, питушок - модифицуй моё последнеер ешение, твоё для знаков тоже не работает.

                                                                              >2. найти усредненную разность двух чисел не решена.
                                                                              Не интересно.


                                                                              >Питушки юлят жопой, когда видят, что не могут осилить задачу.
                                                                              ко-ко-ко. Как жешь питушки любят слится и кукарекать про то, что кто-то не осилил что-то. Но вы тут все похожи - кукарейкайте.
                                                                              Ответить
                                                                              • ты убог
                                                                                Ответить
                                                                                • Я твоего решения вообще не увидел, питушок. Я хоть копипасту питушка на УБ сделал по скорости, а ты?


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

                                                                                Это слив. Ты просто не можешь сделать.
                                                                                Жалкие отмазы не интересно.. Еще скажи что времени нету.
                                                                                Ответить
                                                                        • Питушок уже забенчил и открыл для себя конвейер? А второй вариант вообще юз уб - такого в интернетах не напишут. Давай, шут, кудахчь.
                                                                          Ответить
                                                                      • >я там перепутал and и or
                                                                        А ложку с хуем ты тоже путаешь?
                                                                        Ответить
                                            • показать все, что скрытоПруф или не было. Что за институт? Как давно?
                                              Ответить
                                          • >уже закончили университет?
                                            Я думал тут практически все закончили, ну кроме вайперов, которые не окончили и школы.
                                            Хотя как сказать закончил? Закончил я примерно так как eth0. Но с дипломом. Короче это целая история.
                                            Ответить
                                        • я на intuit даже встречал наш кафедральный курс 1 семестра про все эти деления, умножения, прямые, обратные, дополнительные коды, модифицированные... было весело, семинар неплохо разгружал мозги после ебучих физики и матана
                                          Ответить
                                        • А вы не подскажите, я уже подзабыл и никак найти не могу. Как можно представить сложение с помощью побитовых операций?
                                          Ответить
                                          • > Как можно представить сложение с помощью побитовых операций
                                            А оно надо? Железный сумматор в ALU'шке всяко будет быстрее ;)

                                            Схемы с последовательным переносом:
                                            a, b - биты слагаемых, p - перенос из предыдущего разряда
                                            x - бит результата, y - перенос в следующий разряд

                                            Полусумматор (не принимает переносы):
                                            x = a ^ b
                                            y = a & b

                                            Полный сумматор
                                            x = a ^ b ^ p
                                            y = a & b | a & p | b & p (можно чуть-чуть упростить)

                                            Схемы ускорения переноса приводить не буду, т.к. видел их давно, не помню их толком, для софтовой реализации они бесполезны, да и гуглятся легко.
                                            Ответить
                                            • Да я спрашивал для общего развития, спасибо. ;)
                                              Ответить
                                          • >>Как можно представить сложение с помощью побитовых операций

                                            именно так я и считал среднее арифметическое.
                                            (a & b) << 1 + (a ^ b).

                                            Про переносы, борманд расписал.
                                            Ответить
                                        • >>Умножение, есть прибавление множимого со сдвигом

                                          int Mlt(int a, int b)
                                                  {
                                                      int temp = default(int);
                                                      for (int i = 0; i < b; i++)
                                                      {
                                                          if (((b >> i) & 1) == 1)
                                                              temp += (a << i);
                                                      }
                                                      return temp;
                                                  }
                                          Ответить
                                          • > Умножение, есть прибавление множимого со сдвигом
                                            Ну зачем же это кодировать настолько дословно... Можно хотя бы в столбик, умножая словами (по 32/64 бита за раз). А если нужна скорость - то вместо своих велосипедов стоит присмотреться к GMP.
                                            Ответить
                                            • Но я ведь хочу заняться байтоебством.
                                              Ответить
                                              • > Но я ведь хочу заняться байтоебством.
                                                Умножение в столбик на уровне слов тоже отличное байтоебство ;)
                                                Ответить
                                                • это BCD-ебство
                                                  Ответить
                                                  • > это BCD-ебство
                                                    BCD - питушиное говно, которое можно юзать разве что если ввод-вывод чисел нужен чаще чем расчеты.

                                                    Выше я имел в виду именно нарезку длинного числа на 32 или 64 битные куски (в зависимости от платформы).
                                                    Ответить
                                                • Примерчик можно? :)
                                                  Ответить
                                                  • > Примерчик можно? :)
                                                    Лень набирать. Просто представьте, что 32 или 64 разрядные слова это "цифры" нашего длинного числа. И к этому числу можно применить обычное умножение в столбик (не самый эффективный алгоритм, но работает).
                                                    Ответить
                              • Кстати, как красиво ловить флаг переполнения без ассемблера?
                                Ответить
                                • Есть способ.
                                  Надо сравнить знаки.
                                  Если при сложении разные, то не переполнится.
                                  Если же одинаковые, а знак результата - противоположный, это и есть оно самое.
                                  Ответить
                                  • > Надо сравнить знаки.
                                    Ну с ветвлением я и так могу.
                                    Ответить
                                    • Кто сказал что нам нужны ветвления?
                                      Ответить
                                      • Как ты это "если" сделаешь без ветвления?
                                        Ответить
                                        • Запросто.
                                          Вечерком попробую. Не хочу отвлекаться от интересного.
                                          Ответить
                                        • абстрагируясь от нашего конкретного условия - можно на 0 или 1 (ака false/true) домножить или сдвинуть дополнительное слагаемое (которое, например, будет равно 0x80000000, чисто случайно это число всплыло)
                                          Ответить
                                        • >Как ты это "если" сделаешь без ветвления?
                                          Дефекейт выше правильно говорит, про 0x80000000, то бишь 1<<31. Домножать не надо.

                                          int p=( (sum ^ a) & (sum ^ b) ) >> 31;
                                          http://ideone.com/RDLnpw
                                          Надо просто сдвинуть на 31. Думал это очевидно.
                                          Ответить
                                          • Ответить
                                          • Ну да, а потом домножать...
                                            Ответить
                                            • Зачем домножать? Если нужна маска то знаковый сдвиг сделает -1.
                                              Ответить
                                          • да даже если в лоб - как скорректировать переполнение? к (a + b)/2 прибавить 1 << 31
                                            как узнать что переполнение было? "беззнаковая" сумма получилась меньше, чем любой из аргументов в беззнаковом виде

                                            но на самом деле все эти шашки со знаковыми базируются на том, что всем привычная архитектура использует дополнительные коды
                                            напомню, по сишному (и заодно крестовому) стандарту знаковое целое всего лишь обязано лежать в диапазоне
                                            -|X| .. |X|
                                            , а не
                                            (-|Х|-1) .. |Х|
                                            , и поэтому знаковое переполнение - в общем случае неопределено
                                            Ответить
                                            • > по сишному (и заодно крестовому) стандарту знаковое целое всего лишь обязано лежать в диапазоне -|X| .. |X|

                                              То есть не на двоичных машинах может заглючить?
                                              Думаю невелика беда.

                                              >как узнать что переполнение было?
                                              Уже написал. Бит знака.
                                              >Если же знаки одинаковые, а знак результата - противоположный, это и есть оно самое.
                                              Ответить
                                              • нет, недвоичных машин сишный стандарт неприемлет
                                                а вот, например, прямой или обратный код - вполне
                                                напомню, в обратных кодах нуль представляется в двух ипостасях +0 и -0 (0b00..00 и 0b11..11)
                                                и еще один, ортогональный пример - сам процессор имеет право отличать знаковые от беззнаковых аргументов ну и вместо знакового переполнения засылать прерывание
                                                но это не к x86, понятное дело
                                                Ответить
                                                • > нуль представляется в двух ипостасях +0 и -0
                                                  Да только хотел об этом написать. Что в дополнительном коде исключительный ассиметричный случай 1 << 31.

                                                  Так хорошо. И что дальше?
                                                  X - каково его значение?
                                                  Ответить
                                                  • вот как раз 2^(n-1) - 1, где n - минимальное число бит в типе
                                                    в стандарте выведены в константы <TYPE>_MIN, <TYPE>_MAX

                                                    про биты
                                                    (ниже текст слишком анскиллед мне было лень его писать питухи бтв)
                                                    да, продолжая тему - всем известны эти питушиные анскильные условия sizeof(char) <= sizeof(short) <= и т.д. - так вот из <TYPE>_MIN <TYPE>_MAX следуют минимальные питушиные ограничения на битность каждого простого (изимодного) типа, т.е. char - минимум 8, short и int - 16, long - 32, long long - 64 питушиных попугаев
                                                    Ответить
                                                    • >вот как раз 2^(n-1) - 1
                                                      Ну тогда никаких проблем возникать не должно.
                                                      Там даже детектирование переполнения суммирования с 1 переноса из младших получится.
                                                      Ответить
                                              • > Бит знака.
                                                только вот для беззнаковых это условие несколько иначе
                                                если знаки аргументов разные (0b1111 + 0b0011), либо если одинаковые (0b1111 + 0b1111), переполнение может и там и там случиться
                                                Ответить
                                                • >только вот для беззнаковых
                                                  Что-то подсказывает мне что для беззнаковых понятие "бит знака" бессмысленно.

                                                  Для беззнаковых я бы просто посчитал среднее арифметическое (благо там это весьма просто, всего 4 инструкции) и проверил бы старший бит.
                                                  Ответить
                              • показать все, что скрытоПитушки никогда не напишут лучше царя - это уже давно пора понять. Закругляйся.
                                Ответить
                                • >Питушки никогда не напишут лучше царя
                                  Среднее 2 и 3, будет 3.
                                  Ебать ты тупоносый лузер. Младшую школу сначала закончи.
                                  Ответить
                                  • показать все, что скрыто
                                    inline uint64_t t(uint64_t a, uint64_t b) {  
                                      return (a >> 1) + (b >> 1) + ((a & 1) & (b & 1));
                                    }


                                    Питушок, не кукарекай мне тут - миссклик.
                                    Ответить
                                    • > ((a & 1) & (b & 1))
                                      лишняя операция
                                      Ответить
                                      • >лишняя операция
                                        Да что ты заладил? Не лишняя. Корректировка потерянного разряда переноса с младших битов.

                                        То что можно это было сделать за 4 операции - другое дело.
                                        Ответить
                                        • Я про то, что это можно было сделать за меньшее число действий.
                                          Ответить
                                    • >миссклик
                                      Мышкой код пишешь?

                                      >((a & 1) & (b & 1))
                                      Неоптимально, но принимается.

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

                                          EDIT: хотя, ладно, я добрый. Держи, 4 инструкции, а не 7. Ниче не умеешь, ниче не знаешь, что ты вообще на сишке делаешь?
                                          http://ideone.com/LmgW7c
                                          Ответить
                                          • Мне не интересно - я сделал то, что тебе надо - оптимальней и проще вы не сделаете, ибо я царь.


                                            Я сделал с 1-го раза так-то. Если ты наврал сейчас, то наврёщь потом - я жду пока эти питушки что-то сделают.
                                            Ответить
                                          • показать все, что скрытоНу молодец, выкинул лишнее из моей байды.
                                            Ответить
                                            • >выкинул лишнее из моей байды.

                                              >return (a >> 1) + (b >> 1) + ((a & 1) & (b & 1));
                                              >return (a & b) + ((a ^ b) >> 1);

                                              Ага. Лишнее. Хуй у тебя со рта вытянул.
                                              Давай разность.

                                              Еще ник взял хакер, ёпта. Не позорь имя, блядь. Имя не позорь! Че ты зарегал-то, блядь? Сишка, хакер. Вафел ты, а не хакер.
                                              Ответить
                                              • Краткое содержание треда:
                                                - Реши задачку.
                                                - царь анскилед питушки ко ко ко
                                                Ответить
                                              • На самом деле, для 16тилетнего мне кажется не плохо.
                                                Ответить
                                                • >для 16тилетнего мне кажется не плохо
                                                  Что неплохо? Уметь гуглить в 16 лет.

                                                  Вот приходишь ты такой устраиваться на работу. На собеседовании говоришь "Я могу решить любую задачку. Только вменяемую."
                                                  Тебя принимают. Заходишь, а начальник у тебя Тарас.
                                                  Он вызывает тебя к себе и говорит
                                                  - Привет. Садись. Есть задание: "запилить физику твёрдых выпуклых тел в 2д"
                                                  А ты отвечаешь:
                                                  - "Нахрен они мне. Твердые тела для питухов. У меня от них жопа постоянно болит, и я уже говорил это. Я больше люблю мочу и говно."
                                                  Ответить
                                                  • А он такой прокачался и отвечает: "Иди нахуй питух, я не буду ничего реализовывать, я скачаю бокс2д".
                                                    Но ему до этого ещё долго расти, с его-то тягой к рукоблудию... Даже я не дорос, мне проще запилить небольшой велосипед, попутно узнав что-то новое для себя, чем разбираться в готовом.
                                                    Ответить
                                                • Итого: исходная задача не реализована. По сути реализована для половины значений, и то со второго раза. Хотя конечно по сравнению с твоими попытками - неплохо, да.
                                                  Ответить
                                                • > для 16тилетнего
                                                  Прочитал как "для 16-битного". Тогда понятно, почему он такой.
                                                  Ответить
                                                  • Хм. Он юзает uint64_t, потому что стыдится своих 16 бит.
                                                    Ответить
                                            • Пидарок, где код, который ты обещал на лоре? Давай его выкладывай, хватит пипиську сосать!
                                              слил все батлы!
                                              Ответить
                                          • > Держи, 4 инструкции, а не 7. Ниче не умеешь, ниче не знаешь, что ты вообще на сишке делаешь?
                                            avg(0,3) = 0. Упс. С выводом бага, надо в принтфе поправить на %llu ;)
                                            Ответить
                                        • a&b&1, трудно додуматься?
                                          Ответить
                                          • А. Ну то такое - мелочь. Компилер, думаю, отдуплит.
                                            Ответить
                            • В школе мне было не до срачей и писькомерства в интернете. ;)
                              Ответить
                              • К нам пришёл омега, который сильный _только_ в интернете.
                                Ответить
                                • А где я говорю, что я сильный? ;)
                                  Я такого не говорил, значит я не омега? Или я настолько омега, что слабый даже в интернете? Или я слабый в интернете настолько, что в реальной жизни просто не могу быть омегой?
                                  Но вы какой-то злой, потому я пожалуй прекращу с вами разговаривать. :)
                                  Ответить
                                  • Тут я должен был извиниться, что меня неправильно поняли, поскольку я некорректно выразил свою мысль. Но мне лень и нахер так жить.
                                    Не принимай на свой счёт, я про тебя ничего не хотел сказать. Неявно подразумевался наш новый гость, который только на словах Лев Толстой, а на деле мы все знаем, кто он. Рако-сосачерское поведение часто наблюдается у категоричных омег, потому что ирл он получит по щам и вялым по губам. Соответственно, ему как раз дело только до интернетов.
                                    Моя плохой, предыдущее сообщение считать невалидным или только в контексте этого.
                                    Обещаю пятилетку в три годав следующий раз выдавать больше контекста.
                                    Ответить
                                    • А, а я то думал, чем я так разозлил человека? Можете не извинятся. ;)
                                      Ответить
            • Нипонел, Тарас какое-то говно юзал для открытия файла, а потому любой игорь нас загрузке тормозил?
              Ответить
              • тсарь пыается сказать, что вместо std::ofstream нужно ммапить файл в память читать файл через хегдлер
                Честно говоря, стримы и строки и всякие stl контейнеры, которые в аллокаторе сами растут, это вообще первое, зачем нужны плюсы.
                Ответить
              • Тарас любил жрать говно
                Ответить
    • http://cs320626.vk.me/v320626101/147b/m8UAEqY-81E.jpg
      Ответить
    • платиновый тред
      Ответить

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