+135
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 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
...на помощь нашему укротителю вертолет с местным укротителем."
> эмитирующий
Чего это макрос у тебя испускает?
Это тут компилятор распознал отсутствие обращений к переменным исходного блока, или просто повезло что не упало?
open();
твой код, который ты передал;
close();
Никаких функий, блоков. стеков тут нет.
Пока что я вижу, что то ли
в АСТ-дереве мы передаём по указателю процедуру с неверным списком аргументов, то ли передаваемая процедура не ведёт себя как вложенная.
Кстати, в этом фрагменте нет ни одного слова inline, потому что компилятор умнее всяких курочек.
Откуда трава? Ничего подобного.
PS. Понял, не объясняй. Не совпадет по типу сигнатуры с указателем на функцию, так что дело не в аргументах видимо.
Или у вложенных блоков другая семантика, чем у вложенной функции с передаче указателя на стек первым параметром?
Иногда он не инлайнит то, что нужно - допустим он у тебя есть цикл, для тех же дифуров. тысяич шагов по сетке 1к*1к. Обработку сетки я анрольнул в функции - получилась функция килобайт на 8. Конпелятор её не инлайнит, хотя она вызывается тысячи раз, что даёт тонных оверхеда. Написал инлайн - стало работать в 2раза быстрее.
Поэтому пацаны лучше знают, что надо и когда инлайнить. На лоре был мой тред про L1i.
Я реализовал по твоим заветам, так что в этом объяснении не было смысла.
Лучше раскажи как компилятор не заинлайнив эту функцию сможет обращаться к локальной переменной tarasB в стеке текущего потока? Или если заинлайнить не получится, то будет облом с обращением к переменной и не скомпилируется?
Кто тут достаточно скилед и сможет врубить возможность анализа кода С без ++?
И ещё я помню были похожие сервисы. Может на них удастся код сгенеренный посмотреть?
http://ideone.com/O6a6pd
PS: А, вы не об этом... Тогда разбирайтесь сами.
Если тебя интересует есть ли в коде этой функции замыкания на локальные переменные, то конечно есть, как и в любой нормальной лямбде, пусть в данном случае лямбде для бедных.
http://ideone.com/1SSYXf
P.S. Если, конечно, не писать в стиле Царя, который срал на эти ваши гарантии. Работает в частном случае - и ладно.
Царь не обязан писать код для питохов, я не заидушный питух на конвейере. Я пишу код для людей своего, либо выше скилла. И не юзать фичи только из-за того, что какой-то анскильный питух их не осилил - я не собираюсь.
Был ещё один сервис, похожий на годболт. Не помнишь его названия? Может там удасться проверить си с гнуцицизмом.
Может тот, кто все свои коннекторы рекламировал?
не знаю, я на гейдев не заходил уже давно
форум с донатом это тупость
Эм, там теперь платить надо за участие?
деньги там ни о чем, порядка литра пива, но не вижу смысла
при этом никому нельзя употребить слово дельфин (а также афалина, белуха - вообще никак)
думаю, главного модераста в детстве укусил дельфин, пока он при фотографировании ему пальцем дыхало заткнул - теперь детская травма преследует всю жизнь
скоро дойдут до того, что щеночки и котятки станут вне закона
страшно подумать, если бы туда поциент сунулся со своими петушками, курочками и мелкими яйчишками второго сорта
О. Точно. Почему я пишу ему курочка... Теперь буду писать цыпленочек.
http://www.mysql.com/common/logos/logo-mysql-110x57.png
https://www.youtube.com/watch?v=RQWwTrR5sAk
А что за сишка, который работает только лишь от наличия конпелятора?
Т.е. логика локальной инлайн функции - это область видимости там, где ты её создал, а т.к. это инлайн - это не функция, а макрос, т.е. она лишена поведения функции(она ничего не принимает и не возвращает, а так же на твоём питух call abi - она не будет его юзать).
Так же - питух, инлайн ничем не отличается от макросов и на нём можно строить логику.
Для питухов, которые еле-еле осилил с89 на уровне 3-тиклассника - это "оптимизация", ибо питухи не могут это юзать.
Так же - я могу строить логику на оптимизаторе - на этом построена половина логики glibc. Это компилтайм ветвления и прочее.
А ты, анскильный питух - дальше кукарекай.
http://ideone.com/qaXqce
нихуя, не компилится
>это область видимости там, где ты её создал,
Это относится к ЛОКАЛЬНОЙ.
>а т.к. это инлайн - это не функция, а макрос, т.е. она лишена поведения функции(она ничего не принимает и не возвращает, а так же на твоём питух call abi - она не будет его юзать).
А это уже к инлайну.
Почему ты думаешь, что юзать это в каких-то там хаскелях - это норм, а в сишке типа не норм?
И что за прикол в 8-символьных идентификаторах?
Починил. Он же пишет, что область видимости - это всё, что ты можешь юзать в блоке, в котором ты её определяешь, а не в том, из которого вызываешь.
Да, все верно. Но инлайн здесь соверщенно не при чем.
Да как это. Функция void (FILE*) и указатель void (*)(FILE*). Почему не передаст то?
У ней сигнатура нихуя не void(FILE*)
У неё сигнатура
void(void* outer_stack, FILE* handle).
Без первого параметра она не сможет обращаться к переменным внешнего блока, потому что переменные внешнего блока адресуются от вершины стека, а после вызова вложенной функции вершина стека сдвигается.
Да. В gcc они сделаны не так как в пасцале, в котором такие указатели несовместимы ;) Поэтому у нее сигнатура совпадает (даже без инлайна).
http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
То есть у них сигнатура совпадает что ли?
А как же тогда к переменным внешней функции обращаться?
Адрес относительно своей вершины стека отсосёт, если сделать рекурсивную вложенную функцию.
Пишем говно:
Компилируем:
Итого: на x86 gcc использует регистр ecx для передачи во вложенную функцию адреса блока локальных переменных. Т. е. это будет работать даже на рекурсивных функциях.
Ну здесь указатель на вложенную функцию не юзался, неинтересно ;) С ним код получается прикольней.
Ужас! Теперь ещё придётся разбираться, как работают трамплины.
Да там тупо. В стек высираются 2 команды: Адрес высранного трамплина затем юзается как адрес локальной функции, чтобы его куда-нибудь передать. Естественно при выходе этого трамплина из скопа вызывать его мягко говоря нехорошо, и так будет делать только царь, знающий, что никто не успеет его затереть новыми данными.
P.S. Т.е. питушня программа, юзающая указатели на вложенные функции, из-за исполняемого стека имеет больше шансов на эксплойт, чем любая другая.
А вот всяко против. И екзек-шилды в линухе тоже. Поэтому указатели на локальные функции - питушня.
А их сделать на самом деле можно только двумя способами - или настоящий указатель на функцию, и новая функция на каждый инстанс, как и сделано здесь или в лиспах. Или вместо указателя на функцию надо передавать нечто более сложное, например указатель на объект, в котором есть замкнутые переменные + указатель на функцию, как это делается в крестах, хаскеле и .т.п.
Причем второй способ нельзя юзать в качестве колбеков для классических сишных функций, т.к. там нихрена не указатель на функцию. Именно поэтому в gcc и выбрали первый.
Маловероятно. Очень маловероятно. Не могу придумать способа, чтобы сделать функцию, содержащую вложенные реентерабельной. Контекст ведь нужен не последний, а именно тот самый, в котором брали указатель на локальную функцию.
>> call ___enable_execute_stack
Угумс.
1 раз на старте проги же достаточно вызвать. Чего она будет тормозить.
Прощай, безопасность?
Ёпт, такая сишка - только для питухов.
Ну а как еще. Не питушиться же со страничками постоянно. Один хуй 4-8 килобайт придется открыть на исполнение ради одного трамплина... Меньше странички же права никак не настроить.
> Прощай, безопасность?
Угу. Привет эксплойты ;) Если без исполняемого стека в линухе сейчас эксплойт запустить довольно сложно - работает рандомизация адреса стека и библиотек, и почти всегда прога крашится, вместо того, чтобы исполнить произвольный код. То здесь открытые ворота. Переполняй буфер по самый трамплин, и исполняй ;) Хотя царям питухов насрать. У них буфера в стеке никогда не переполняется, ибо они "знают свою платформу".
> Ёпт, такая сишка - только для питухов
Ну если никогда не брать указатель на локальные функции - исполняемый стек не активируется, так что не так все ужасно.
P.S. Не, ну безусловно можно было сделать чуть безопаснее - запилить read-write-execute пул, в который складываются трамплины. Но т.к. в сишке нет деструкторов, это могло бы привести к утечкам на всяких там setjmp/longjmp.
Поэтому функции питушня, стек питушня и нахрен не упал и всё это питушня. Инлайн должен спасать от этих проблем, но гцц питух не хочет нормально инлайнить. Надо пропатчить питуха.
У царей нет буферов на стеке, ибо стек питух.
А кучу цари не юзают, ибо медленная. Поэтому все переменные у царей глобальные.
> Инлайн должен спасать от этих проблем
Ага, превращая прогу в стометровое говно.
Поэтому регистры и куча.
Нет, инлайн не превращает ничего в 100метровое говно, просто ты юзаешь питухлибы, функции в которых 100метровое говно.
Реально инлайн не увиличивает длинну нормально написанного кода, а нааборот уменьшает. А если код питух - он итак будет 100метровый, хотя есть питухдинамиклибы, которые типа избавляют вас от этих проблем.
Какие-то питухочудеса!
Как вставка кода может уменьшить объем этого самого кода. И с примером пожалуйста.
и в последнюю очередь - убертюнинг перформанса, когда в питушиный кеш питушиных инструкций может перестать влезать и перформанс упадет, как будто его писал анскильный питух
во всех остальных случаях мелкие функции проще объявлять инлайновыми (причем, в c++ они с большой вероятностью будут такими изза шаблонности или описания прямо в теле класса)
в любом случае компилятор при включенной оптимизации сам разберется, что инлайнить, что нет - независимо от наших рекомендаций
Даже понтовый гцц тот ещё питух и иногда фейлит с инлайном, поэтому проще написать инлайн и быть уверенным в нормальной порятнке, чем гадать.
Простые функции вроде max при инлайне займут меньше инструкций, т.к. при вызове функций обычно нужно сохранять состояния нескольких регистров на стеке.
А вот если ты заюзаешь инлайн, то все функции уйдут и конпелятор сможет равнометрно распределить код по регистрам, не юзать питухстек и не дампить регистры простотак.
Потом не забывай, что обычно инлайн функции маленькие и их тело примерно равно оверхеду на их вызов.
Потом, обычно вся жара происходит в циклах, а для циклов анрол всего даёт нереальный буст как к скорости, так и к поможет l1i. Один фиг твои функции будут вызываться редко, а по коду программа будет бегать много - шанс на то, что все твои функции будут в l1i не большой( хотя есть хороший префеч - один фиг запрефечить портянку проще), плюс оверхеды на вызовы и т.п.
В конечном итоге инлайн проиграет только в тех случаях, когда у тебя будут поочерёдно вызваться 100разных функции, в которые будут инлайнится 1 большая инлайн функция и это всё будет юзаться в цикле и 100разных функции с вызовом большой "инлайн" функции влезут в l1i, а с инлайном уже нет. Такое маловероятно.
Т.е. это касается больше анрола, чем инлайна.
Нет, стек не питух, это буфер - питух.
Я сейчас говорю только про х86.
Т.е. запилить на них реальнонормальный софтварный стековый аллоктор, который нежрёт регистры и моя идея с заменой в ваших плюсах ГЦ(всякие виды автоптров, деструкторы и прочее) на софтварный стек - реализовывалась ещё проще.
На нормальной ОС и 64битном питухе стек может быть безразмерный с постоянными адресами.
Благо от этой питушни с попами ушли, что хоть радует.
Освободить регистор можно только если поступить по-фортрановски - все локальные переменные всех функций имеют фиксированные адреса. Никакой рекурсии при этом уже быть не может.
А рекурсию можно запилить и так, да и она нахрен не упёрлась
Нужен тебе стек - вводи ключевое слово recursive и конпелятор будет юзать софтварный стек, который может быть бесконечен, если бесконечна твоя оператива. Это даст возможность тебе вызвать рекурсию миллиарды раз.
А там, где функция не рекурсивная - там конпелятор может юзать на 2 регистра больше.
Например, для обхода в глубину. Да, можно руками эмулировать FIFO-контейнер, ну и ради чего?
Переделать ветвящуюся рекурсию в цикл - только если вручную хранить цепочку данных о вызовах функций, то есть опять же - руками эмулировать стек.
> Нужен тебе стек - вводи ключевое слово recursive
Это питушня, компилятор должен уметь сам определять, рекурсивна ли функция.
>Это питушня, компилятор должен уметь сам определять, рекурсивна ли функция.
Твой паскаль нихрена не умеет определять - ты же не ноешь? Пусть определяет и юзает там стек, но в остальных стек пусть не юзает, а регистры юзает, но не под стек.
Ручками его умулировать?
А ещё при статическом размещении локальных переменных функций эти самые переменные могут быть раскиданы по всей оперативе, в отличие от стека, где все они аккуратно собраны в одном месте.
И прыгать по оперативе - это просто пиздец насколько дороже, чем лишний раз переложить из регистра в регистр.
> Твой паскаль нихрена не умеет определять - ты же не ноешь?
В моём Паскале реализация рекурсивной функции не отличается от реализации просто-функции, потому что и те, и те просто используют стек. Поэтому ему не нужен определятор рекурсии.
Конпелятором, только у тебя будет специальный стек для каждой функции, который может быть бесконечен.
>А ещё при статическом размещении локальных переменных функций эти самые переменные могут быть раскиданы по всей оперативе, в отличие от стека, где все они аккуратно собраны в одном месте.
В регистрах, в регистрах. Инициализаторы и константы с кодом в l1i.
Какраз-таки наоборот. Статик укомпонован и выравнен нормально. Всё рядышком - всё отлично. Прыгать по аперативе дёшево, если ты юзаешь страницы нормально( а в stl ты не юзаешь страницы нормально и у тебя ОМГПИТУХ оверхед, и это последние, о чём тебе надо думать).
В функции всё хранится только в регистрах, никаких стеков/куч и прочего. Никакой статической памяти и прочего - только регистры.
>В моём Паскале реализация рекурсивной функции не отличается от реализации просто-функции, потому что и те, и те просто используют стек. Поэтому ему не нужен определятор рекурсии.
Поэтому он тормазит как питух. Стек устарел ещё лет 15назад.
Поэтому повторю ещё раз. В функция для переменных юзаются ТОЛЬКО регистры. Работа с кучей через указатели(адреса), как и раньше.
Функции вызываются, а аргументы передаются через регистры, либо функция инлайнится.
Если функция рекурсивная, то конпелятор юзает кучу, как стек, а указатели хранит в стековых регистрах.
Здравствуй перфоманс и ещё 2регистра.
А если регистров не хватит?
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 вложенных функций или нет, я спрашиваю, что делать, если всё-таки это произошло. Использовать стек?
У тебя 4-5 штук есть ещё, а если уж и их нехватит - есть всякие фпу регистры, а уж если их не хватит, то дампь в кучу.
>И занять регистр. И что делать, если 10 вложенных функций вызываются? Я не спрашиваю, питушня 10 вложенных функций или нет, я спрашиваю, что делать, если всё-таки это произошло. Использовать стек?
ОДИН, а не два. И только только внутри функции, который можно задампить в кучу.
Да, ты можешь юзать стек. Я уже говорил про это. У тебя в регистре есть ещё местро на 1адрес, но юзай стек.
Суть в том, что вменяемая архиктура, вменяемое устройство СУЩЕСТВУЕТ ТОЛЬКО ДЛЯ МИРА НОРМАЛЬНОГО КОДА. А для мира питухов - есть х86 говно и С++.
Пора с этого говна линять, но начать хотябы с запила общих теорий. У этой теории есть 2 основных постулата: код пишет не питух и его не интересуют анскилледы и конпелятор продолжение руки программиста. Конпелятор это не питушня, которая гинерит код и должна быть неведомым чёрным ящиком - а вменяемая, предсказуемая, подстраивающиеся под програмиста стредство помощи, которое будет делать рутинную работу. Это не замена мозгу, чтобы из питушарского говнокода делать более-менее, как задача процессора исполнять, а не пытаться оптимизировать говнокод.
Как-то так.
Либо нужно генерировать код, совместимый с возможной рекурсией, либо реализовывать свой Фортран с яйцами и курочками, в котором даже косвенная рекурсия запрещена.
Составлять граф вызовов, искать циклы.
А если ты юзаешь компилтайм скрытую рекурсию над рандомными функциями в рантаймгинерируемых указателях, то твой код питушня и ты ничего не слышал о перфомансе.
Из-за таких питухов как вы, со своими либами и проприетарщиной и придумывают всякие кастыли типа лто.
Питухи всё.
или начни хотя бы с ядра
Все эти модули, лто и т.п. запилена для плюсов, которые собираются тыщи лет, ибо код говно и хрен распарсишь, хрен заоптимизируешь и хрен нагинеришь.
Чуть подоптимизировать конпеляторы, выпилить лишние питух-оптимизации, писать нормальный код и можно миллионны строк мержить.
Итого : указатель на блок таки передаётся, а наше using его не передаёт, то есть код таки говно.
Только если вложенная функция вызывается из блока, в котором она описана. Если передать по указателю - генерится другой код.
Там в стеке генерится трамплин с mov ecx, контекст; jmp вложенная функция. Вот адрес этого трамплина и передается туда, где его будут использовать.
Его внешяя функция генерирует до вызова using и этот using какого-то хрена должен знать, что ecx надо сохранить до вызова калобяки?
Функция, внутри которой описана локальная функция в тот момент, когда она хочет куда-то передать указатель на локальную функцию.
> должен знать, что ecx надо сохранить до вызова калобяки
Согласно cdecl: Registers EAX, ECX, and EDX are caller-saved, and the rest are callee-saved, поэтому всем насрать.
> динамическая кококодогенерация тут по сути
Надо попробовать написать какую-нибудь высокопроизводительную питушню с генерацией кода прямо в стеке.
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.
Что ты хотел своей пастой показать - я не понял.
Вот это например хотел показать. Что в стандарте нигде не сказано, что компилятор что-то обязан инлайнить. Т.е. в твоем случае это надо смотреть в мане от gcc, и никогда не говорить, что "обязан по стандарту" ;)
Ну да. Сам по себе С99 компилятор код для инлайн функции не сгенерит, согласен. Можно заставить его сгенерить такой код, но это уже не автоматика.
Тараса он тут какбэ формально не заинлайнил, но по факту - это инлайн. Поэксперементировать можно, авось можно выпилить кал, но мне пока лениво.
Любой вменяемый компилятор умеет гццизмы. А если он их не умеет, то этот компилятор - бесполезное никому не нужное говно, и юзать его я не буду.
Разве ты не знал, питушок, что любой вменяемый компилятор умеет гццизмы. А если этот питуханский питухокомпилятор их не умеет - то его писали анскильные питухи, и это бесполезный, никому не нужный куриныйпитушиный помёт, который юзать будут только питушки-анскилябры, но не я.
Но этом в овер 50% случаях не надо, ибо открытие и закрытие файлов - это питушня гуйявская.
Тарас же геймдев питушок? Вот юзай пулы с хедлерами.
Хотя тыж маздайский питушок, у тебя там хоть fstat() есть? Или ты как питушок чтобы узнать длинну файла его читаешь?
Чего люди не придумают, а лишь только потому, что их питух ОС нихрена не может.
Я кажется понимаю откуда у тебя знания по конпеляторам из msvs2003, ибо такую бездарную питушню может нести только адепт питухконпелятора.
Я полностью клал на перфоманс операции, выполняющейся раз в несколько минут и длящейся меньше десятой доли секунды :D
Пиздишь.
В отличие от школохакеров, я умею определять, какое место в коде надо ускорять, а какое можно оставить как есть.
> Т.е. ты юзаешь фуфло, которые в 20раз тормазнее, для которого надо в 10раз больше кода писать и оправдываешь это тем, что ты клал на всё?
> в 10раз больше кода
Пиздишь.
как он будет столкновения определять?
У меня как бы есть бонус - отсутствие трения и да-да, фиксированная запятая. У бокс2Д есть бонус - это скилл авторов.
Как тут: https://play.google.com/store/apps/details?id=tarasB.FluidArkanoid.free
это если у тебя есть ведроидная мобила
Выкатывай референсный код, описание задачи, критирии "правильности"(правдоподобности). Твой скрин выглядит как питушня, а правдоподобности я там не вижу.
Пилить хрен знает что из-за кукареканья питушка я не собираюсь.
Да.
Такой формулировки нормальному человек достаточно, чтобы понять, что от него хотят. Ну, если только он не питух анскильный, как ты.
Того, что я сказал, достаточно, чтобы понять задачу. Примеры и код нужны только питухам.
Значит задачу смени, если критерии не можешь выработать для этой
А питушки орут "запили мне то, незнаю что".
например, упругое столкновение двух шаров известных размеров и известной инерции - посчитать в каких координатах окажутся эти шары спустя t наносекунд после столкновения
но код для этого давать - зачем
это элементарная задача первого курса института - т.е. где тебе никогда не оказаться в связи с твоим предельным слабоумием и полнейшим отсутствием абстрактного мышления
Мне лениво гуглить и думать что и как тебе там надо, а когда у меня есть - я сразу вижу, что мне надо сделать и делаю. Почитай ветку на лоре - пока референс не выкатили никто не понимал что вообще надо делать. Правда там референс с фейлом - он ничего не считает.
Так же и тут - ты пишешь портянку, которой показываешь что ты от меня хочешь.
Я не спрашивал питухов, ты настолько анскилен, что даже вменяемого говорить со мной не юля не можешь. Где твой вуз? абстрактное мышление? Я знаю, что ты начился лора и начал повторять, но ты питух, жалкий и безмозглый.
в аналитическом, геометрическом и даже в твоем петушином смысле
ты не понимал, зачем нужны отрицательные числа - открой для себя координатную сетку, вектора и проекции
задачу на лоре тебе дали не самую простую - численные методы это не программа 1 курса, но они не думали, что ты настолько анскиллен
я же тебе тарасовскую программу упрощаю в такую элементарную задачу, здесь даже производная особо не нужна
думаю, она тебе понятна на пальцах, её можно потрогать - если нет, сходи купи два бильярдных шара, желательно разного веса и размера - деньги у мамки попросишь
ты же считаешь себя гением
первокурсники себя гениями не считают, но такие задачи щёлкают, как орехи
люди не заканчивают школу (редкий случай, да), потому что считают, что всё что в ней дадут - они освоят самостоятельно за полчаса - такая же логика относится и к тем, кто не заканчивает институтов (такое чаще бывает)
мне в школе было скучно, самым трудным было себя заставить тратить время и марать бумагу, пока пишешь устные ответы на задачи в одно действие
итак, анскильный тарас решил такую задачу, причем постарался сделать это оптимально для своей платформы как умел
никто за тебя её решать не собирается, давать какой то референсный код - пока что тебе засчитается сам факт, что ты получишь примерно правильный ответ
а потом тарас тебе расскажет где конкретно узкие места и почему ему понадобился фиксед, ок?
Только ты убрал то место, в котором фикседы лажают - рассчитать несимметричный удар с учётом момента инерции. Там формулы-то простые, но порядки величин прыгают так, что я заипался их переставлять, и всё равно в отладочном режиме иногда программа вылетает с "переполнение целых".
> а потом тарас тебе расскажет где конкретно узкие места
Оно кстати вовсе не в расталкивании тел у меня было, а в определении точки контакта двух выпуклых многоугольников.
Не надо.
1. Я хочу увидеть незамутненное решение от гуру.
2. ЕМНИП там не было верного решения
Я тоже :)
Может скиллед нам подскажет?
и ты теперь этим гордишься?
ты в бильярд играл когда-нибудь?
задача интуитивна
куриному царю достаточно сложения и вычитания, чтобы доширак купить и чтобы со сдачей не обманули
ты нулище и твой мозг размером с горох, надеюсь, что ты всё же троль примерно из снг (судя по времени отхода ко сну), а не умственный инвалид из челябинска, которого кормят моими же налогами
Найти среднее арифметическое двух целых чисел, то бишь двух интов.
У тебя есть шанс проявить себя.
Язык - сишка, кресты, шарп, жаба. Для определенности.
Нужно написать функцию, с сигнатурой:
int avg(int a,int b).
intы - знаковые
Ну и задача должна легко масштабироваться на long и прочие целые.
На остальную питушню, сингеты, переполнение и прочее - я клал.
Впрочем для знаковых твой код тоже сработает, молодец.
> ((a & 1) | (b & 1))
лишняя операция
Реально? Ну выпили питушок, авось поймёшь для чего это нужно.
диссоциативное расстройство идентичности?
Сосать повсюду и чистить хозяйский толчок.
Попробуй еще раз. Только чтоб правильно считало.
Умею. А что нужно прочитать?
http://ideone.com/iYen1I
Ты - гавно!
t(12,13)=13
>твой код тоже сработает, молодец.
Соснул хуец.
Есть два числа, интовые, тебе нужно поделить одно на другое, не используя операции умножения и деления.
Помню делал такое на шарпе, но у меня некрасиво получилось.
Мне даже понравилось. Думаю все таки возьмусь за плюсы. Это весело ;)
Делал я такое. Несколько раз. До универа, последний раз в универе. Кстати преподы дали в методичке глючный алгоритм, но я её не читал и делал по-своему, потому у меня единственного оно работало корректно.
Умножение, есть прибавление множимого со сдвигом (есть в множителе 1 или нет), ок?
Деление - умножение на магическое число. Это первый способ, хорошо для констант.
Второй способ - обычное деление в столбик для двоичной системы. Я его люблю больше. Сдвигаем,если больше, отнимаем и пишем 1 в результат, иначе пишем ноль, опять сдвигаем. итд...
С корнями чуть сложнее.
Давно. Кстати тех способов что там учили я так и не понял. Объясняли их как-то через жопу, отличались всего-лишь тем что сдвигать в какую сторону.
>только если делишь на константу.
Я указал это.
Вообще бОльшую практическую ценность представляет деление больших чисел, тоже в столбик, но, используя систему с машинным основанием. У Кнута эта тема описана.
Ну то есть по 32/64 бита за раз.
Этот код неправильно сработает на числах 12 и 13 же.
Вариант кулцхакера лучше в этом.
Wut? Вы вообще тестировали?
http://ideone.com/gGOuF8
>Вариант кулцхакера лучше в этом.
Он хуже. Во всем.
12 - 1100
13 - 1101
Потом идет xor и в итоге 0001
Далее сдвиг, в итоге 0.
И о прибавляется к 12. В итоге 12, а должно быть 13.
То есть сишное целочисленное деление тоже неправильное работает, потому что округляет вниз?
25/2, должно быть 13?
Хм, каникулы?
Ну если вы округляли всегда в меньшую, то тогда вопросов нет.
Но задачу нужно решать не в направлении того, как работают какие-то структуры яп'а.
:)
Причем в шарпе есть исправления для таких округлений.
Полагаю это вариант в интернете, по запросу "найти среднее двух чисел без регистрации и переполнения".
Так там в выдаче неправильные говноспособы.
И ответы либо кепа, либо чувак, используй jquery LINQ.
В том-то и прикол, что какую-то справочную инфу, какой класс, метод, реверс строки итп - просто нагуглить.
А такую задачку - хер. В выдаче гугла один мусор.
Даже наверное попробую с переменным числом аргументов.
Вот, пожалуйста, третья ссылка по запросу "найти среднее двух чисел без регистрации и переполнения": http://forum.sources.ru/index.php?showtopic=312681&view=showall
Охереть. Годно.
Я просто на англицком гуглил - ерунда сплошная.
А вот искомая проблема. Как красиво провести коррекцию?
http://www.google.com/search?q=average+of+two+numbers
>> (x&y) + ((x^y) >> 1)
Это классика, блядь. Это знать надо, если ты мнишь себя хукиром.
Разность, без переполнений.
Вижу у тебя жопа болит, потому что твой способ оказался говном.
Держи ещё 1 вариант, питух. Вариации не тему.
Питух.
Не работает:
Проверяй свою питушню - у тебя питушарское переполнение. Он не может не работать.
Я разность просил, идиотина.
Главное что он быстрее.
К тому же твой первый вариант - говно.
avg(2,3)=3
Хоть бы он работал быстрее света, он НЕПРАВИЛЬНЫЙ.
А теперь, пожалуйста, усредненную разность двух чисел.
avgSub(100,50)=(100-50)/2=25.
Это неважно, потому твой способ тормозной, а ты уёбок и хуй.
Покушал говнеца на ровном месте.
Ты уже написал сотню комментов, а изменить свой код так чтоб он выдавал усредненную разность двух чисел не можешь.
Значит ты тупоносый лабась, который взял чужое и даже не разобрался.
Чужое? Т.е. я взял чужое, и специально перепутал? Ок. ТруЪ логика, пацантра - она даже не вызвает у меня улыбки - настолько правдоподобна.
> Т.е. я взял чужое, и специально перепутал?
Поставленная задача:
1. найти среднее арифметическое двух знаковых чисел не решена.
2. найти усредненную разность двух чисел не решена.
http://govnokod.ru/13183#comment181848
Питушки юлят жопой, когда видят, что не могут осилить задачу.
Со знаками идёт нахрен, питушок - модифицуй моё последнеер ешение, твоё для знаков тоже не работает.
>2. найти усредненную разность двух чисел не решена.
Не интересно.
>Питушки юлят жопой, когда видят, что не могут осилить задачу.
ко-ко-ко. Как жешь питушки любят слится и кукарекать про то, что кто-то не осилил что-то. Но вы тут все похожи - кукарейкайте.
Вот так и получается. Питушки кукарекует в темах, примеры приводят лишь из своего жалкого узкого круга примитивной специализации - широта кругозора 0. Нихрена не умеют. Вот и вылазиют питушки.
>Не интересно.
Это слив. Ты просто не можешь сделать.
Жалкие отмазы не интересно.. Еще скажи что времени нету.
А ложку с хуем ты тоже путаешь?
Я думал тут практически все закончили, ну кроме вайперов, которые не окончили и школы.
Хотя как сказать закончил? Закончил я примерно так как eth0. Но с дипломом. Короче это целая история.
А оно надо? Железный сумматор в 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).
Про переносы, борманд расписал.
Ну зачем же это кодировать настолько дословно... Можно хотя бы в столбик, умножая словами (по 32/64 бита за раз). А если нужна скорость - то вместо своих велосипедов стоит присмотреться к GMP.
Умножение в столбик на уровне слов тоже отличное байтоебство ;)
BCD - питушиное говно, которое можно юзать разве что если ввод-вывод чисел нужен чаще чем расчеты.
Выше я имел в виду именно нарезку длинного числа на 32 или 64 битные куски (в зависимости от платформы).
Лень набирать. Просто представьте, что 32 или 64 разрядные слова это "цифры" нашего длинного числа. И к этому числу можно применить обычное умножение в столбик (не самый эффективный алгоритм, но работает).
Надо сравнить знаки.
Если при сложении разные, то не переполнится.
Если же одинаковые, а знак результата - противоположный, это и есть оно самое.
Ну с ветвлением я и так могу.
Вечерком попробую. Не хочу отвлекаться от интересного.
Дефекейт выше правильно говорит, про 0x80000000, то бишь 1<<31. Домножать не надо.
int p=( (sum ^ a) & (sum ^ b) ) >> 31;
http://ideone.com/RDLnpw
Надо просто сдвинуть на 31. Думал это очевидно.
как узнать что переполнение было? "беззнаковая" сумма получилась меньше, чем любой из аргументов в беззнаковом виде
но на самом деле все эти шашки со знаковыми базируются на том, что всем привычная архитектура использует дополнительные коды
напомню, по сишному (и заодно крестовому) стандарту знаковое целое всего лишь обязано лежать в диапазоне , а не , и поэтому знаковое переполнение - в общем случае неопределено
То есть не на двоичных машинах может заглючить?
Думаю невелика беда.
>как узнать что переполнение было?
Уже написал. Бит знака.
>Если же знаки одинаковые, а знак результата - противоположный, это и есть оно самое.
а вот, например, прямой или обратный код - вполне
напомню, в обратных кодах нуль представляется в двух ипостасях +0 и -0 (0b00..00 и 0b11..11)
и еще один, ортогональный пример - сам процессор имеет право отличать знаковые от беззнаковых аргументов ну и вместо знакового переполнения засылать прерывание
но это не к x86, понятное дело
Да только хотел об этом написать. Что в дополнительном коде исключительный ассиметричный случай 1 << 31.
Так хорошо. И что дальше?
X - каково его значение?
в стандарте выведены в константы <TYPE>_MIN, <TYPE>_MAX
про биты
(ниже текст слишком анскиллед мне было лень его писать питухи бтв)
да, продолжая тему - всем известны эти питушиные анскильные условия sizeof(char) <= sizeof(short) <= и т.д. - так вот из <TYPE>_MIN <TYPE>_MAX следуют минимальные питушиные ограничения на битность каждого простого (изимодного) типа, т.е. char - минимум 8, short и int - 16, long - 32, long long - 64 питушиных попугаев
Ну тогда никаких проблем возникать не должно.
Там даже детектирование переполнения суммирования с 1 переноса из младших получится.
только вот для беззнаковых это условие несколько иначе
если знаки аргументов разные (0b1111 + 0b0011), либо если одинаковые (0b1111 + 0b1111), переполнение может и там и там случиться
Что-то подсказывает мне что для беззнаковых понятие "бит знака" бессмысленно.
Для беззнаковых я бы просто посчитал среднее арифметическое (благо там это весьма просто, всего 4 инструкции) и проверил бы старший бит.
Среднее 2 и 3, будет 3.
Ебать ты тупоносый лузер. Младшую школу сначала закончи.
Питушок, не кукарекай мне тут - миссклик.
лишняя операция
Да что ты заладил? Не лишняя. Корректировка потерянного разряда переноса с младших битов.
То что можно это было сделать за 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 лет.
Вот приходишь ты такой устраиваться на работу. На собеседовании говоришь "Я могу решить любую задачку. Только вменяемую."
Тебя принимают. Заходишь, а начальник у тебя Тарас.
Он вызывает тебя к себе и говорит
- Привет. Садись. Есть задание: "запилить физику твёрдых выпуклых тел в 2д"
А ты отвечаешь:
- "Нахрен они мне. Твердые тела для питухов. У меня от них жопа постоянно болит, и я уже говорил это. Я больше люблю мочу и говно."
Но ему до этого ещё долго расти, с его-то тягой к рукоблудию... Даже я не дорос, мне проще запилить небольшой велосипед, попутно узнав что-то новое для себя, чем разбираться в готовом.
Прочитал как "для 16-битного". Тогда понятно, почему он такой.
слил все батлы!
avg(0,3) = 0. Упс. С выводом бага, надо в принтфе поправить на %llu ;)
Я такого не говорил, значит я не омега? Или я настолько омега, что слабый даже в интернете? Или я слабый в интернете настолько, что в реальной жизни просто не могу быть омегой?
Но вы какой-то злой, потому я пожалуй прекращу с вами разговаривать. :)
Не принимай на свой счёт, я про тебя ничего не хотел сказать. Неявно подразумевался наш новый гость, который только на словах Лев Толстой, а на деле мы все знаем, кто он. Рако-сосачерское поведение часто наблюдается у категоричных омег, потому что ирл он получит по щам и вялым по губам. Соответственно, ему как раз дело только до интернетов.
Моя плохой, предыдущее сообщение считать невалидным или только в контексте этого.
Обещаю пятилетку в три годав следующий раз выдавать больше контекста.
Честно говоря, стримы и строки и всякие stl контейнеры, которые в аллокаторе сами растут, это вообще первое, зачем нужны плюсы.