- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
#include "HelloWorld.h"
namespace HelloWorld {
CoreLib::System::RuntimeType pituh::__type = CoreLib::System::RuntimeType(&HelloWorld::pituh::__rt_info);
// Method : pituh.pituh()
void pituh::_ctor()
{
base::_ctor();
return;
}
// Method :
CoreLib::System::Type* pituh::__get_type()
{
return &HelloWorld::pituh::__type;
}
// Method :
bool pituh::__is_type(CoreLib::System::Type* value)
{
return ((&HelloWorld::pituh::__type == value) || base::__is_type(value));
}
// Method :
void* pituh::__get_interface(CoreLib::System::Type* value)
{
return base::__get_interface(value);
}
// Method : pituh.Main(string[])
int32_t pituh::Main(__array<string*>* args)
{
CoreLib::System::Console::WriteLine(u"Kokoko!"_s);
return 0;
}
pituh::__type_methods_table pituh::_methods_table;
__runtimetype_info pituh::__rt_info = { u"pituh", u"", 18, false, &object::__type, nullptr };
}
auto __main(int32_t argc, char* argv[]) -> int32_t
{
__startup();
auto exit_code = HelloWorld::pituh::Main(__get_arguments(argc, argv));
__shutdown();
return exit_code;
}
auto main(int32_t argc, char* argv[]) -> int32_t
{
return __main(argc, argv);
}
Вот такой красивый говнокод получается после прогонки С# HelloWorld в С++
и хедор на закуску
PS: было уже
Зачем все эти отрицания, коль есть Except?
а так всё таки
> object
> __array
> string
мне сильно кажется что здесь С++ и не пахнет.
вот. из CoreLib.h
а вот вижимка для __array
на кой фиг это надо? кто делает ГЦ? догадываюсь что все равно привязано к дотнету и виндам?
Вообще я всё меньше понимаю зачем нужен ГЦ.
кроме поддержки циклических ссылок он ничем не лучше референс каунтинга, а референс каунтинг быстрее, легче, понятнее, и вообще
Сомнительное утверждение. Для объектов без деструкторов с коротким временем жизни ГЦ с поколениями может быть в среднем ощутимо быстрее, особенно когда счётчики ссылок должны быть атомарными. Без конкретных замеров затрат на различных юзкейсах это всё голословно.
> ничем не лучше референс каунтинга
Дефрагментация кучи.
но ГЦ все же требует отдельного потока и (иногда) стоп зе ворлд
Яблоко говорит что дескать они меньше едят батарею чем андроид потому что у них не гц а рефкаунтинг
>>Дефрагментация кучи.
да, тут я погорячился
гц вроде ищет пути к объектам из стеков потоков и стат памяти, и если нет -- выпиливает
но там есть жесткие правила кто ссыль увеличивает, а кто нет
грубо говоря функция useFoo(*bar) увеличивает ссылку на bar, а abuseFoo -- нет
на каждый выход ссылки из зоны видимости уменьшает счетчик?
Загружая при этом процессор под сотку
вот пример
единственная ссылка на память(обьект) Boo находиться только в стеке и если в этот момент вызвать GCCollect и не проверить стэк то обьект Boo будет удален а значить вызов Bla::Foo приведет к Memory Access ошибке
потому что шарп использует гц. что значит что шарпов код явно объекты выделяет, но явно ее *не* освобождает.
> Вообще я всё меньше понимаю зачем нужен ГЦ.
> кроме поддержки циклических ссылок
именно. результат: проще семантика.
> он ничем не лучше референс каунтинга,
референс каунтинг - отстой. я его делал пару раз в ручную, и толку от него было мало. если дата модель позволяет использовать референс каунтинг без граблей, то там и до детерменистического life cycle объектов не далеко. а если у объектов детерменистический life cycle, то гц и не надо: если знаешь точно когда можно/нужно удалять объекты, то не велика работа их удалить.
на самом деле, полноценный гц - это просто облегчение жизни. ну как коробка-автомат: профи ругаются что типа не эффективно, а всем кому просто из А в Б доехать надо это приятная (не)мелочь.
Не знаю является-ли работа с памятью частью требования к ЯП. Хотя ключ слова delete в нем нет, и метода release у System.Object (а это стдлиба япа) тоже нет.
>>референс каунтинг без граблей,
каких граблей?
Я создал объект и ссылка пошла гулять по куче. Как мне узнать когда его можно того?
> каких граблей?
типичные грабли это (классика) циклические зависимости, (то с чем я еще мучался) когда объекты друг на друга многократно ссылаются и (то с чем еще больше мучался) когда владение объектом передаётся от одного объекта другому.
реф-каунтинг часто приходится дебажить - а дебажить его сложно. хез почему реф-каунт резко -Н стал, или почему он вечно Н и не уменьшается. я когда последний раз делал, в лоб делал мап с реляциями между указателями объектов (что тоже через ж работало потому что пара классов лежало в векторе, который сам себя перевыделял, и все поинтеры резко менялись).
да, это не решается без гц
я про это сразу сказал
я понял про грабли
типа такого
https://developer.apple.com/reference/foundation/nsautoreleasepool
Мне кажется, это отвлекает, рассеивает внимание программиста, уводит от цели, понижает понятность. Вместо того, чтобы работать над алгоритмом, программист работает над тем, чтобы разложить байты вручную.
А потом само мышление начинает исключать случаи, где отсутствие гц - боль. Например, по условию из функции возвращаем либо переданный объект, либо объект по умолчанию; из функции возвращает либо элемент переданной коллекции, либо новый созданный элемент. Без гц и подсчёта ссылок повезёт, если такие "либо-либо" возвращают объекты с разными классами владельцев (как в первом случае), а то вообще могут возвратить какую-то странную питушню (как во втором случае). Программисту приходится городить подсчёт ссылок/копирование или претворяться, что вообще таких способов передачи ссылок не существует.
> Мне кажется, это отвлекает, рассеивает внимание программиста, уводит от цели, понижает понятность
ты выдрал из контекста. речь шла о реф-каунтинге. редкий язык его нативно поддерживает - что значит что в общем случае надо самому ручками прикручивать. явное удаление - против явного реф-каунтинга, я не уверен что хуже.
Получается относительно не плохо: не надо руками писать retain (+) и release (-) но нужно учитывать что:
1) циклические ссылки это мемори лик. Так что ВЕЗДЕ есть четкие правила в какую сторону нужно иметь weak reference. Это нужно помнить и соблюдать.
2) если функция создает объект и возвращает его, она вынуждена увеличить ссылку (потому что без ссылки он сразу коллектница), но кто должен уменьшить эту ссылку потом? Вызывающая сторона не знает отдали-ли ей новый объект или старый (это то, о чем говорит 1024). Для этого есть тот самый pool в который кладутся такие объекты и потом он коллектится (обычно в конце евентлупа)
3) наконец рефкаунтинг не работает для плейнси. Там надо самому делать retain/release, причем надо помнить что функции с названием create делают reatin а get -- нет (говорю по памяти но правила именно такие -- по НЕЙМНИГУ)
Так что это конечно проще чем вручную делать free, но внимательность всё равно нужна
А как ви себе это представляете, переносимый способ убирать ворнинги? Насколько я знаю, стандарт си/плюсов вообще никак не затрагивае тему того, что есть какие-то там ворнинги. Нужно добавить это в стандарт? Под плюсы даже name mangling никто не стандартизировал(что кстати является проблемой куда серьезнее), какие к дьяволу стандартизации варнингов?
Плохо знаешь:
"— If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message."
diagnostic message и есть warning. Еще, из с++17:
http://en.cppreference.com/w/cpp/language/attributes
Вообще не вижу проблемы ввести аттрибут аля [[nowarn]] или [[nowarn=sign-compare]]
> Под плюсы даже name mangling никто не стандартизировал(что кстати является проблемой куда серьезнее)
Потому что для этого надо стандартизировать calling conventions и сделать один из них стандартным по умолчанию. Можешь представить, сколько программ это сломает? Какого члена они не стандартизировали эти вещи с самого начала? Наверно, производители компиляторов сыграли в "лебедь, рак и щука"
И конечно же копеляторы должны были генерить код под свою платформу чтобы интероптица с уже существующим кодом
Да, действительно. Не думал, что они ПРО ЭТО напишут в стандарте.
>Вообще не вижу проблемы ввести аттрибут аля [[nowarn]] или [[nowarn=sign-compare]]
И написать еще в стандарте подробнейший список того, на что должен и на что не должен выдавать варнинг компилятор (с примерами кода), и что вот этому варнингу соответствует "sign-compare", вот этому "NULL-dereference-possible", а этому "undefined-behaviour-div0"? Не, я не говорю что это невозможно сделать, просто есть задачи поприоритетней.
В идеале я считаю из компилятора вообще надо выкинуть все варнинги(кроме тех, из-за которых код тупо не компилируется, но это уже не варнинги, это ошибки компиляции). Потому что анализаторы, встроенные в разные компиляторы могут с разным успехом диагностировать разные ошибки, и например может иметь смысл прогонять некий код и через анализатор gcc и анализатор clang, потому что множество варнингов, которые может выдать gcc но не clang и выдать clang но не gcc, т.е. симметрическая разность двух множеств варнингов для разных компиляторов будет не пустой, так не лучше ли отцепить анализатор от компилятора, чтобы применять его отдельно? Ну как PVS-studio какую-то. На кой черт это надо обязательно заставлять делать при компиляции?
Да приоритеты на самом деле даже не очень-то и при чем. Простые вещи вряд ли вызовут сопротивление общественности. Это ж не какие-нибудь модули, где производители компиляторов срутся друг с другом у кого реализация лучше, пока пользователи ждут.
> На кой черт это надо обязательно заставлять делать при компиляции?
Статический анализ многократно дольше компиляции, а диагностики компилятора не налагают существенных затрат. Вот и выходит, что проще ловить простые ошибки (типа опечаток) на лету, а на сложные пусть сервер проверяет анализатором перед коммитом.
Статический анализ (как и компиляция) может быть разным. Например, компиляция каких-нибудь constexpr-функций, которые в компилтайме что-то сложное делают, может занять на порядок больше времени, чем их будет проверять статический анализатор.
> а диагностики компилятора не налагают существенных затрат. Вот и выходит, что проще ловить простые ошибки (типа опечаток) на лету, а на сложные пусть сервер проверяет анализатором перед коммитом
Ну так можно запускать статический анализатор в облегченном режиме, чтобы он анализировал это так же, как это делает компилятор, не вижу в этом никаких проблем. Например, перед коммитами мне вот действительно приходится компилировать, но конечным результатом (скомпилированным бинарем) я не пользуюсь, и компилирую я именно чтобы отловить всякие тупые ошибки. Т.е. фактически компилировать мне не надо, мне нужны только варнинги, и всякие там юнит-тесты запускаются не у меня на компе.
Спасибо, ты мне напомнил про С++/CLI, и где теперь мой обед.
если ты хранишь int и ксоришь его чтобы получать адрес то никто (кроме тебя) не знает что это ссыль или указатель
тут не раьботает ни гц ни рефкаунт
> явное удаление - против явного реф-каунтинга
Я писал про пользу неявного с гц. Действительно, написал комментарий не по теме.
вот что использованно для ГЦ
https://www.hboehm.info/gc/
Кросплатформенная либа работает везде
C# async
Развернуло в 1 метод + 1 класс
и дохрена кода ...
Swift tool to transform DOS/PMODEW 386 TASM Assembly code to C code
Только там надо какой-то свифт ставить, чтобы это собрать
https://github.com/libretro/mrboom-libretro
Конвертированный код выглядит довольно мерзко:
https://raw.githubusercontent.com/libretro/mrboom-libretro/master/mrboom.c
> .xcodeproj
Там ещё какой-то мак нужно ставить, чтобы это собрать.
Непорядок. Засор.
сказал проктолог так нельзя
и стал вытаскивать из глеба
ферзя
Сказал проктолог. Так нельзя!..
И стал вытаскивать из Глеба
Большого черного ферзя.
Пример (копировать сюда не буду из-за размера):
http://web.archive.org/web/20100615232803/paste.lisp.org/display/73134
А теперь представим, что получится, если сначала прогнать C# → C++, а потом C++ → С.
Красота-то какая! Комитет решил добавить синтаксис для того, что бы пользователь помогал компилятору выводить типы?
А что зелёным? Именно для этого и прикрутили эту хрень...
decltype(a + b) foo(T1 a, T2 b) {
PS. Да, я знаю, что a и b ещё не объявлены. Но неужели нельзя было как во всяких там Сишарпиках делать? Не нужны были бы эти "предварительные объявления" (или как они там, в крестах?)
И даже без AST, сразу строчат машинный код?
И при этом оптимайзер всё равно делает 100500 заходов, чтобы упростить всю высранную однопроходным фронтендом метушню...
1. Директива forward у функции, чтобы можно было создавать косвенную рекурсию. Аналог в няшной — голый прототип.
2. Можно объявить указатель на ещё не полностью определённый тип. Используется, например, для создания связных списков.
Сишный аналог кода:
Извращенцы могут определить в Object Pascal указатель на функцию, принимающую указатель на такую же функцию и/или возвращающую указатель на такую же функцию:
А как с этим в няшной и в крестах?
А если бы там был не указатель то фиг.
Вероятно потому что для подсчета размера указателя не нужно знать весь тип, а для размера типа нужно.
Об заднепроходном компиляторе
Сомневаюсь. Скорее всего, проблема в потенциальном сокрытии имён.
Но ведь имена - это не проблема для компилятора. Можно сразу после парсинга поменять местами список аргументов и возвращаемый тип, после чего на это AST отдать на вход алгоритмам (а таковые реализованы, т.к. компиляторы C++11 существуют).
Остаются только людские сомнения, которым в C++ уже противостоят работающие исключения из простых правил:
Преждевременное использование неинициализированной питушни (аргументов) - тоже не проблема как для компилятора, так и для человека, т.к. вещи вида struct X { X():x(0){} int x; }; работают.
И область видимости, не покрытая фигурными скобками - тоже не проблема как для компилятора, так и для человека, т.к. аргументы функции объявляются где-то вне фигурных скобок, опоясывающих тело, а видны только внутри них.
Как по мне, если и вносить инородную питушню, то хотя бы что-то реальное полезное и более удобное. Например, сделать наконец работающие typedefы для функций и обновить описания типов.
Я говорю, что decltype(a+b) f — это говно, потому-то возникает проблема с именами. Тебе кажется логичным, что имена должны привязываться к параметрам, а мне — наоборот.
Что то говно, что это говно.
swift, kotlin.
А откуда вообще в сишке такой говносинтаксис?
Ritchie's idea was to declare identifiers in contexts resembling their use: "declaration reflects use".
Видимо, хотели, чтобы было "интуитивненько", по заветам 1024--, типа Получилось как всегда.
ага, отсюда же и char *foo, c
потому что c = *foo
фу таким быть!
> "declaration reflects use"
Нельзя с первого раза поработать с памятью без утечек и UB.
Нельзя с первого раза объявить несколько указателей.
Например, #pragma link, #pragma library, #pragma comment (lib), призванные хоть как-то компенсировать отсутствие модульности, так и не стали стандартом. Да даже диапазоны в switch-case есть только у gcc.
Вы не подумайте: я люблю няшную, код люблю писать, а вот читать -- нет.
Вот она, метушиная сила - любую хуйню можно сделать.
Мне кажется, было бы не так надёжно. Если случайно разогнётся один палец, то результат изменится на какое-то число от 2^0 до 2^9 вместо единицы.
Ну и число "3" (или "20") показывать сложно (невозможно?).
Если взять только все доступные среднему человеку кобенации с пальцами и фалангами, уже сложно будет запомнить, не пытаться корячиться и восстановить число по положению пальцев.
Кстати да, какая бы система счисления была бы у нас, если бы был выбран вариант счёта с использованием всех физически доступных кобенаций пальцев и фаланг? Наверно какая-нибудь странная питушня вроде дюймов, футов, миль или дней в месяцах. Во всяком случае, во французском языке, если не ошибаюсь, 80..89 уже сейчас именуют как семьдесят десять, семьдесят одиннадцать, ..., семьдесят девятнадцать, а где-то ещё в цивилизованной Европе не гнушаются названий вида "пару раз сорок плюс треть пятнадцати". И это только с загибанием пальцев согласно количеству!
G@