Đây là câu chuyện: Tôi đang phát triển phần mềm C++ cho bộ xử lý ARM Cortex-M0 trong Linux với AC6 Toolpack. Trước khi tôi sử dụng Keil (trong các cửa sổ) (người có chuỗi công cụ riêng của họ) và tôi đã chuyển sang GNU-toolchain ((Công cụ GNU dành cho Bộ xử lý nhúng ARM) 5.2.1). Điều đầu tiên tôi đã nhận ra là; kích thước tệp nhị phân tăng đáng kể. Tôi đã thử nghiệm mọi tối ưu hóa trình biên dịch (ngoại trừ tối ưu hóa thời gian liên kết, nó đưa ra một lỗi trong lắp ráp nội tuyến, không phải là một phần của câu hỏi nhưng có thể liên quan đến câu trả lời). Sau đó bắt đầu kiểm tra các tập tin thực thi (tập tin elf không bin, gnu sản xuất cả hai) với bất kỳ công cụ có sẵn: objdump, readelf, nm. Tôi đã tìm thấy một số biểu tượng gây ra tăng kích thước, các biểu tượng quan trọng là: 'd_print_comp_inner
', 'd_exprlist
', 'd_template_args
'. Nhưng không có ý tưởng những gì đang gây ra các chức năng này xuất hiện trong nhị phân. (tôi đã sử dụng các thư viện tối thiểu: nano newlib). Truyện ngắn tôi bắt đầu loại bỏ từng mã một để tìm ra thủ phạm. Cuối cùng nó đã được khai báo phương pháp trừu tượng!Khai báo lớp trừu tượng (phương pháp ảo thuần túy) tăng kích thước nhị phân đáng kể
Xác định chức năng như
virtual Return_type function_name(...)=0;
thay vì
virtual Return_type function_name(...);
thêm 45 KB và những biểu tượng tôi đã đề cập. Và đây là thay đổi duy nhất trong mã nguồn. Định nghĩa rỗng trong lớp cơ sở là hiện tại. Lưu ý rằng: Phương pháp vẫn còn ảo và ghi đè trong các lớp con
Kích đầu ra mà không Abstract Class:
text data bss dec hex filename
15316 24 4764 20104 4e88 temc_discovery.elf
Kích đầu ra với Abstract Class:
text data bss dec hex filename
61484 128 4796 66408 10368 temc_discovery.elf
Ở đây, các biểu tượng và kích thước của họ mà hiển thị khi phương thức trừu tượng, loại bỏ các phương thức hiển thị trong cả hai phiên bản. (nm
công cụ được sử dụng. Không danh sách đầy đủ, là những người có kích thước> = 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
Một số cái tên quen thuộc đối với tôi (như printf, tuôn ra, malloc, fputs vv) được thậm chí không được đề cập trong nguồn mã.
Bất kỳ ai có bất kỳ ý tưởng nào đang gây ra hành vi này?
Cập nhật: tôi đã được vô hiệu hóa ngoại lệ với cờ --noexception
, vì vậy tôi đã không đưa ra bất kỳ mặc dù với nó. Khi nó quay ra, nó có liên quan đến câu trả lời rất tốt để đề cập đến điều này ở đây.
Cập nhật 2: This is the most comprehensive website giải thích tất cả, nếu bạn theo dõi liên kết trong câu trả lời.
Nó có thể là tốt hơn để cung cấp các biên dịch và liên kết lệnh, ví dụ Tùy chọn '-g' sẽ tạo ra nhị phân lớn hơn cho các biểu tượng gỡ lỗi, v.v. Và bạn có thể kiểm tra kích thước nhị phân bị tước. – Mine
Như tôi buồn, tôi đã thử tất cả các tối ưu hóa trình biên dịch. Cùng một kết quả (với mức tăng cao hơn 40 KB). – ifyalciner
Giải pháp. có lẽ, đã được đưa ra ở đây: https://stackoverflow.com/questions/14689639/can-i-disable-exceptions-for-when-a-pure-virtual-function-is-called – deniss