EmbDev.net

Forum: ARM programming with GCC/GNU tools Program size explodes when using the "new" operator


von ARTHUR W. (arthur_w)


Attached files:

Rate this post
useful
not useful
Hello !

I am using Code Sourcery's GNU toolchain to code for the LXPXpresso 
LPC1769 board.
Just a word before you think I understand more than I do : this is my 
first step outside of the arduino world ( after a few days in the mBed 
world ).
So I'm trying to code for it in C++. A simple "blinking" example works 
ok.
But when I try to do oop, and use the "new" keyword, the program's size 
explodes : 

Without the "new" keyword : 
1
arm-none-eabi-size main.elf
2
   text     data      bss      dec      hex  filename
3
    768        8        8      784      310  main.elf

With the "new" keyword : 
1
arm-none-eabi-size main.elf
2
   text     data      bss      dec      hex  filename
3
  82264     1424     2136    85824    14f40  main.elf

That's a lot of flash usage for just a small keyword. A similar test in 
the mBed online compiler gives no visible difference ( it rounds code 
size to kilobytes ) between using new or not using it.

So I have googled quite a lot about this. The most usefull command I 
have found is this : 
1
arm-none-eabi-nm --demangle --print-size --size-sort --reverse-sort -S main.elf
2
00003400 00005202 t d_print_comp
3
0000d190 00001640 T _svfprintf_r
4
00008604 00000ede t d_print_mod
5
0000eb2c 00000eba T _dtoa_r
6
00010db4 00000ae0 T _svfiprintf_r
7
100005a8 00000800 b emergency_buffer
8
00001ad8 0000071c t d_type
9
000094e4 00000696 t d_print_mod_list
10
0000bd18 0000057a T _malloc_r
11
0000298c 00000544 t d_encoding
12
0000c790 0000041c T _realloc_r
13
10000100 00000408 D __malloc_av_
14
etc ...

So it looks like using the new keyword also gets printf and other space 
consuming things into the program. I don't want it to do that, that's 
stupid.
It seems like there are two reasons why it would do that ( from what I 
have googled, I understand like 3% of it ) : 

1. Maybe it puts all of libstdc++ into the program, and does not delete 
what is not needed.
But the makefile does -ffunction-sections at compilation and 
--gc-sections at linking, and from what I have understood if you do that 
useless stuff gets discarded. So either --gc-sections does not work, or 
that's not the problem.

2. Maybe it includes code for "exceptions", which from what I understand 
( probably wrong ) is like runtime errors or something. So it would make 
sense it needs printf to report errors ... The problem is that in my 
makefile I have -fno-exceptions. So either -fno-exceptions does not work 
correctly, or it is not the problem ...

This is as far as I was able to go with my knowledge and google ...
I am attaching a zip of the project ( it's like a frankeinstein 
creature, with bits of everything I was able to find on the internet, 
please don't mock it ).

I would be extremely gratefull for any help in getting the code size to 
a reasonable size.
Thank you very much in advance for your help !

Arthur.

von mimo (Guest)


Rate this post
useful
not useful
Hi Athur,
If you are using the "new" keyword, a complete heapmanager must be 
included in ur source. This larger code is the price to pay for dynamic 
ram management.
Hope that would help a bit.

von (prx) A. K. (prx)


Rate this post
useful
not useful
The newlib isn't great for small sized controllers, as it tends to pull 
in quite a bit of unwanted dependencies in addition to the actual 
library functions used. If you cannot avoid dynamic memory allocation, 
avoid the newlib and implement you own memory allocation runtime 
functions instead.

The same holds for the frequently used printf function. The newlib 
version actually needs much more code as simple replacements found on 
the web, especially when floating point support is not required.

von ARTHUR W. (arthur_w)


Rate this post
useful
not useful
1
arm-none-eabi-size main.elf
2
   text     data      bss      dec      hex  filename
3
   3912     1296       72     5280     14a0  main.elf

Fixed !

The culprit was codesourcery's libstdc++, which did not respond 
correctly to -fno-exceptions. Replaced it with a libstdc++ that had no 
exception handling, and now it works !
Using new takes only 3144 bytes more in size, much closed to what I 
excepted.

Thank you for the help !

( details of the fix here 
: http://mbed.org/forum/mbed/topic/2336/?page=1#comment-11861 )

von flozn (Guest)


Attached files:

Rate this post
useful
not useful
hey arthur,

i experienced a similar problem. my binary size exploded when using only 
a few of my c++ content (just statical instantiation of classes).

after analyzing the biggest symbols i reached this thread. obviously the 
exception-management was included although -fno-exceptions was provided.

as i understood you changed your libstdc++-library to another selfmade 
one which doesn't support exceptions.

for me another solution was fine:
because your link was dead i searched further and further and reached 
some site where the exception-handling problem with enabled 
-fno-exceptions also persists.
http://elegantinvention.com/blog/information/smaller-binary-size-with-c-on-baremetal-g/

the main content for reducing code size by avoiding c++-exceptions are 
the following steps:
- providing -fno-exceptions (obviously)
- no usage of new, delete (a workaround code is provided in the link -> 
attached file)
- provide function for pure virtual call, e.g.
1
extern "C" void __cxa_pure_virtual() { while(1); }
- overwrite the internal function for handling unhandled exceptions - 
the name-demangling is very big (e.g d_print_comp.part.10 with 9.5k or 
d_type with 1.8k) and can be avoided by own handling

at my project the code size was reduced by providing the pure virtual 
call target about 30k (with optimize size -Os and remove unused sections 
by -Wl,--gc-sections -fdata-sections -ffunction-sections)!

cheers
flo

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.