Вот история: Я разрабатываю программное обеспечение C++ для процессора ARM Cortex-M0 в Linux с помощью AC6 Toolpack. До того, как я использовал Keil (в окнах) (у кого есть своя инструментальная цепочка), и я перешел на GNU-toolchain ((GNU Tools for ARM Embedded Processors) 5.2.1). Первое, что я понял; размер бинарного файла существенно увеличился. Я тестировал каждую оптимизацию компилятора (за исключением оптимизации времени ссылки, она дает ошибку в встроенной сборке, а не в вопросе, но может быть связана с ответом). Затем начал проверять исполняемые файлы (файл elf не bin, gnu производит оба) с любым доступным инструментом: objdump, readelf, nm. Я нашел несколько символов, вызывающих увеличение размера, значимыми являются: 'd_print_comp_inner
', 'd_exprlist
', 'd_template_args
'. Но понятия не имею, что вызывает появление этих функций в двоичном формате. (я использовал минимальные библиотеки: nano newlib). Короче говоря, я начал устранять коды один за другим, чтобы найти виновника. Наконец, это было объявление абстрактного метода!Объявление абстрактного класса (чистый виртуальный метод) значительно увеличивает размер двоичного кода
Определение функции, как
virtual Return_type function_name(...)=0;
вместо
virtual Return_type function_name(...);
добавление 45 KB и символы, которые я упомянул. И это единственное изменение в исходном коде. Существует пустое определение в базовом классе. Обратите внимание, что: метод еще виртуальный и переопределены в дочерних классах
Размер выходные без абстрактного класса: выход
text data bss dec hex filename
15316 24 4764 20104 4e88 temc_discovery.elf
Размера с абстрактным классом:
text data bss dec hex filename
61484 128 4796 66408 10368 temc_discovery.elf
Здесь символы и ихнего размером, что появляется, когда метод абстрактный, устранены те, которые отображаются в обеих версиях. (nm
инструмент используется. Не полный список, те, с размером> = 0x60)
00002de4 t d_print_comp_inner
00001a34 t d_exprlist
00000ca4 t d_template_args
00000678 t d_type
00000574 t d_print_mod
000003f8 t d_encoding
000003e0 r cplus_demangle_operators
000003c8 t d_expression_1
000003a8 t d_name
00000354 t d_demangle_callback.constprop.15
000002e0 t d_print_mod_list
00000294 r cplus_demangle_builtin_types
00000268 t d_unqualified_name
00000244 T _printf_i
00000238 t d_print_function_type.isra.11
000001fc T _svfprintf_r
000001fc T _svfiprintf_r
000001f4 t d_print_array_type.isra.10
000001ce t d_print_cast.isra.12
0000018c t d_substitution
00000110 t d_operator_name
0000010c T __sflush_r
000000e8 T __swsetup_r
000000e6 t d_cv_qualifiers
000000e0 t d_print_subexpr
000000e0 t d_expr_primary
000000dc T _printf_common
000000cc T __cxa_demangle
000000c8 t d_source_name
000000c4 r standard_subs
000000c4 T __ssputs_r
000000b0 T __swbuf_r
000000ac T _malloc_r
000000a8 T _fputs_r
000000a4 T __smakebuf_r
000000a0 T __gnu_cxx::__verbose_terminate_handler()
00000096 t d_print_expr_op
0000008c T _free_r
0000008c t d_parmlist
0000008a t d_growable_string_callback_adapter
0000007c T __sfp
00000072 t d_append_buffer
00000068 T __sinit
00000060 d impure_data
Некоторые имена, знакомые мне (такие как Printf, утопленного, таНос, fputs и т.д.) даже не упоминается в источнике код.
Любое лицо с какой-либо мыслью, что вызывает подобное поведение?
Update: Я уже отключить исключения с флагом --noexception
, так что я не дали, хотя к нему. Как выясняется, это связано с тем, что так хорошо говорить об этом здесь.
Update 2: This is the most comprehensive website объяснить все это, если вы отслеживать ссылки в ответах.
Это может быть лучше, чтобы обеспечить команду компиляции и ссылку, например, Опция '-g' будет генерировать большие двоичные файлы для отладочных символов и т. д. И вы можете проверить размер разделенного двоичного файла. – Mine
Как мне грустно, я пробовал все оптимизации компилятора. Тот же результат (с более высоким увеличением 40 КБ). – ifyalciner
Решение. вероятно, уже здесь: https://stackoverflow.com/questions/14689639/can-i-disable-exceptions-for-when-a-pure-virtual-function-is-called – deniss