여기 진 크기를 증가는 이야기입니다. Keil을 사용하기 전에 (자신의 툴체인이있는) Windows 용 GNU-toolchain (ARM 임베디드 프로세서 용 GNU Tools) 5.2.1)로 마이그레이션했습니다. 내가 처음 깨달은 것은; 바이너리 파일 크기가 크게 증가했습니다. 모든 컴파일러 최적화를 테스트했습니다 (링크 시간 최적화를 제외하고는 인라인 어셈블리에 오류가 발생하고 질문에는 포함되지 않지만 대답과 관련 될 수 있음). 그런 다음 사용 가능한 도구 (objdump, readelf, nm)를 사용하여 실행 파일을 검사하기 시작했습니다 (elf 파일은 bin이 아니며 gnu는 두 파일 모두를 생성합니다). 내가 크기 증가의 원인이 일부 기호를 발견, 중요한 사람은 'd_print_comp_inner
', 'd_exprlist
', 'd_template_args
'. 그러나이 기능이 바이너리로 나타나게하는 원인이 무엇인지 모릅니다. (나는 최소한의 라이브러리를 사용했다 : nano newlib). 길고 짧게 나는 범인을 찾기 위해 하나씩 코드를 제거하기 시작했다. 마침내 추상적 인 메소드 선언이었습니다!선언 추상 클래스 (순수 가상 메서드) 실질적으로
정의 기능 45킬로바이트 및 I 언급 한 심볼을 추가
virtual Return_type function_name(...)=0;
대신
virtual Return_type function_name(...);
있다. 그리고 이것은 소스 코드에서 유일한 변화입니다. 기본 클래스의 빈 정의가 있습니다. 방법은 여전히 가상과 추상 클래스하지 않고 자식 클래스
크기 출력에서 재정의 :주의 추상 클래스와
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
나 (등 fputs의 printf, 플러시, malloc에, 등)에 익숙한 일부 이름은 심지어 소스에 언급되지 않은 암호.
이 문제의 원인을 어떤 생각으로 어떤 하나?
업데이트 : 이미 플래그 --noexception
에 예외를 해제했다, 그래서 나는 그것에 비록 어떤을 부여하지 않았습니다. 그것이 밝혀 졌을 때, 이것은 여기에 언급하기에 너무 좋은 대답과 관련이 있습니다. 당신이 답변에 링크를 추적하는 경우, 모든 것을 설명 This is the most comprehensive website :
업데이트 2.
컴파일 및 링크 명령을 제공하기 위해 더 좋을 수있다, 예를 들어, libc의 버전에서 변경 될 수 있습니다 비록 내가, 우리의 프로젝트가 무엇인가 '-g' 옵션은 디버그 심볼 등을위한 더 큰 바이너리를 생성 할 것이다. 그리고 여러분은 스트립 된 바이너리의 크기를 검사 할 수있다. – Mine
슬픈 것처럼 모든 컴파일러 최적화를 시도했습니다. 동일한 결과 (40KB 증가). – ifyalciner
해결책. 아마도 여기에 이미 나와 있습니다 : https://stackoverflow.com/questions/14689639/can-i-disable-exceptions-for-when-a-pure-virtual-function-is-called – deniss