К сожалению, я плохо понимаю теорию языков программирования, поэтому не знаю, почему нельзя просто сделать тип Type или вроде того.
Вроде бы в Питоне так можно. И в Руби вроде есть класс Class. Хм. Может, к этому больше тяготеют языки с динамической типизацией, потому что там люди вынуждены тип в рантайме проверять.
Такое решение подходит для тех случаев, когда исходный тип известен в месте работы с ним. Но что делать, если это не так? Что делать, если вызывающий код просто не знает об исходном типе объекта в месте его использования? Тогда нам нужно как-то запомнить исходный тип, взять его там, где он определен, и сохранить наряду с типажом-объектом dyn Any, чтобы потом последний привести к исходному типу в нужном месте.
Если было можно просто сохранить исходный тип объекта как обычное поле в самом объекте и потом скастовать к нему, то не потребовалось ничего изобретать. Если я правильно понял статью, конечно.
Енам, насколько я понимаю, не подходит, потому что нужно будет заранее знать все возможные исходные типы, чтобы их потом явно перебрать.
Представьте, что можно делать как-то так (прошу прощения для псевдо-С++):
class A { Type realType; };
class B : A
{
}
B b;
A * a = &b;
a.realType = typeof(b);
auto p = a as a.realType; // <<- auto выводит тип В
Возможно, мысль несколько мимо темы, но как было бы здорово, если бы типы тоже были first class citizens, как функции; т.е. чтобы была встроенная в язык возможность хранить тип в рантайме.
Даже не знаю, есть ли языки, где так можно делать?
Мне кажется, что довольно вещей можно было бы делать проще и чище.
У Кейла, внезапно, есть две реализации malloc/free с разной асимптотикой (линейной и логарифмической, по-умолчанию линейная). Возможно, если это и правда баг, его можно полечить, сменив реализацию.
Да, речь тут только про вспомогательную память на куче, которая требуется для деструкторов статичских объектов. В куче создается только список каких-то записей про объекты, а не они сами.
Вообще, если хочется поиграться, то начиная с Кейла 5.23 примерно можно выбрать другой компилятор — armclang, форк clang'a, — который вполне умеет в С++14. И стандартная библиотека к нему идет нормальная, а не от С++03.
Я лично им пока побаиваюсь пользоваться в продакшене, потому что некоторые вещи там еще сыроваты, но потрогать уже можно. Заодно время компиляции снижается очень значительно.
Поправка, на самом деле все немного не так, но это не очень существенно:
Спойлер
до main'a при каждом вызове конструктора статического или глобального объекта, через длинную цепочку вызывается __aeabi_atexit, который должен "зарегистрировать" этот объект для удаления после вызова main'a (когда вызывается _sys_exit).
Я в очередной раз повелся на название "atexit", но не суть, работать это работает.
А ведь до того момента я об ее объеме даже и задумывался. На черта ли сдалась мне эта куча, полагал я. Все равно у меня все переменные и объекты либо статические, либо лежат на стеке. Так, просто по инерции оставил под нее 0х300 байт, раз уж какой-то объем под кучу выделяется во всех шаблонных проектах. Ан нет вот, для рантайма С++ все равно нужна динамически выделяемая память, причем в достаточно заметных, по меркам контроллеров, количествах.
С этим можно справится, если переопределить функцию, которая вызывается после main'a. Если у вас ARM (и Keil), то эта функция называется __aeabi_atexit. Если сделать ее пустой, то куча будет не нужна.
int __aeabi_atexit(void)
{
return 1;
}
Я вообще предпочитаю делать #pragma import(__use_no_heap_region), чтобы сразу получать ошибку компиляции, если кто-то где-то пытается трогать кучу.
А не подскажите прозрачный клей, которым можно стекло со стеклом склеивать? Желательно не слишком жидкий, чтобы им можно было примерно как герметиком пользоваться. "Прозрачный" силиконовый герметик при этом слишком мутный :(
В общем случае неверно, сильно зависит от компилятора и опций оптимизации.
Соглашусь, но если коллстек строит IDE, то это не принципиально. А руками стек разбирать мне все равно не очень хочется.
Вообще, если памяти не запредельное количество — делать полный дамп озу и регистров хорошая идея. Полный слепок в момент падения, позволяет сделать больше чем только стектрейс.
Тоже соглашусь, просто мне это было не успело понадобиться.
Если все равно выводить адреса, а не текстовые имена функций, то какая разница? Все равно копировать и отладчику скармливать. Разве что дамп будет поменьше.
А, там по классике — пока другое исправлял, та ошибка нашлась и минидамп не успел пригодиться.
Как оказалось, я серверу кидал некорректный запрос и сервер мне возвращал свой собственный стектрейс :) Который мне массив для ответа и переполнял.
К сожалению, я плохо понимаю теорию языков программирования, поэтому не знаю, почему нельзя просто сделать тип Type или вроде того.
Вроде бы в Питоне так можно. И в Руби вроде есть класс Class. Хм. Может, к этому больше тяготеют языки с динамической типизацией, потому что там люди вынуждены тип в рантайме проверять.
Процитирую проблему из статьи:
Если было можно просто сохранить исходный тип объекта как обычное поле в самом объекте и потом скастовать к нему, то не потребовалось ничего изобретать. Если я правильно понял статью, конечно.
Енам, насколько я понимаю, не подходит, потому что нужно будет заранее знать все возможные исходные типы, чтобы их потом явно перебрать.
Представьте, что можно делать как-то так (прошу прощения для псевдо-С++):
Возможно, мысль несколько мимо темы, но как было бы здорово, если бы типы тоже были first class citizens, как функции; т.е. чтобы была встроенная в язык возможность хранить тип в рантайме.
Даже не знаю, есть ли языки, где так можно делать?
Мне кажется, что довольно вещей можно было бы делать проще и чище.
У Кейла, внезапно, есть две реализации malloc/free с разной асимптотикой (линейной и логарифмической, по-умолчанию линейная). Возможно, если это и правда баг, его можно полечить, сменив реализацию.
http://www.keil.com/support/man/docs/armlib/armlib_chr1358938928135.htm
Да, речь тут только про вспомогательную память на куче, которая требуется для деструкторов статичских объектов. В куче создается только список каких-то записей про объекты, а не они сами.
Ага, он самый.
Большинство страшных ошибок из-за несовместимости опций со старым компилятором, тут лучше создавать пустой проект заново.
Вообще, если хочется поиграться, то начиная с Кейла 5.23 примерно можно выбрать другой компилятор — armclang, форк clang'a, — который вполне умеет в С++14. И стандартная библиотека к нему идет нормальная, а не от С++03.
Я лично им пока побаиваюсь пользоваться в продакшене, потому что некоторые вещи там еще сыроваты, но потрогать уже можно. Заодно время компиляции снижается очень значительно.
Поправка, на самом деле все немного не так, но это не очень существенно:
до main'a при каждом вызове конструктора статического или глобального объекта, через длинную цепочку вызывается __aeabi_atexit, который должен "зарегистрировать" этот объект для удаления после вызова main'a (когда вызывается _sys_exit).
Я в очередной раз повелся на название "atexit", но не суть, работать это работает.
Уточню, переопределение __aeabi_atexit поможет только от вот этого вызова деструкторов для статических объектов после завершения main.
С этим можно справится, если переопределить функцию, которая вызывается после main'a. Если у вас ARM (и Keil), то эта функция называется
__aeabi_atexit
. Если сделать ее пустой, то куча будет не нужна.Я вообще предпочитаю делать
#pragma import(__use_no_heap_region)
, чтобы сразу получать ошибку компиляции, если кто-то где-то пытается трогать кучу.Не, спасибо, мне не срочно :)
Спасибо еще раз :)
Спасибо! А "самозастывающих" не бывает, случайно?
А в чем шутка? По вики вроде вполне подходит...
А не подскажите прозрачный клей, которым можно стекло со стеклом склеивать? Желательно не слишком жидкий, чтобы им можно было примерно как герметиком пользоваться. "Прозрачный" силиконовый герметик при этом слишком мутный :(
Соглашусь, но если коллстек строит IDE, то это не принципиально. А руками стек разбирать мне все равно не очень хочется.
Тоже соглашусь, просто мне это было не успело понадобиться.
Да, обычный кейловский бинарь axf это вроде просто elf. Но вот как раз на мысли парсить артефакты мне резко захотелось забить.
Если все равно выводить адреса, а не текстовые имена функций, то какая разница? Все равно копировать и отладчику скармливать. Разве что дамп будет поменьше.
А, там по классике — пока другое исправлял, та ошибка нашлась и минидамп не успел пригодиться.
Как оказалось, я серверу кидал некорректный запрос и сервер мне возвращал свой собственный стектрейс :) Который мне массив для ответа и переполнял.
А, спасибо.