Moją magisterkę na ARMa z 8k flash i 32k flash piszę w hardcore C++ z:
- obiektami
- szablonami
- metaprogramowaniem (łącznie z testem, czy boost::mpl zadziała) W planach właśnie dodanie polimorfizmu dynamicznego.
Dopisałem do projektu następujące klasy: class foo{ public: virtual void f(){uart_print("foo\r\n");} }; class bar:public foo{ void f(){uart_print("bar\r\n");} }; class foobar:public bar{ void f(){uart_print("foobar\r\n");} }; class oof:public foo{ void f(){uart_print("oof\r\n");} };
I do main dopisałem: int ll=uart_read_int(); foo f; bar b; foobar fb; oof o; foo* ff; if(ll==1){ ff=&f; }else if(ll==2){ ff=&b; }if(ll==3){ ff=&fb; }else{ ff=&o; } ff->f();
Binarka przytyła po tym o 200 bajtów: text data bss dec hex filename 4012 8 168 4188 105c firmware.elf 4212 8 168 4388 1124 firmware2.elf
- 28 bajtów to sam wypisywany tekst
- po 8 bajtów na metodę [1]
- 48 bajtów dodatkowego kodu w main (o tym za chwilę)
- po 16 bajtów na vtable dla klasy
W main został wygenerowany następujący kod: 0x000006a4 <+56>: ldr r3, [pc, #224] ; (0x788 <main()+284>) 0x000006a6 <+58>: str r3, [sp, #4] 0x000006a8 <+60>: ldr r3, [pc, #224] ; (0x78c <main()+288>) 0x000006aa <+62>: str r3, [sp, #8] 0x000006ac <+64>: ldr r3, [pc, #224] ; (0x790 <main()+292>) 0x000006ae <+66>: str r3, [sp, #12] 0x000006b0 <+68>: ldr r3, [pc, #224] ; (0x794 <main()+296>) 0x000006b2 <+70>: str r3, [sp, #16] 0x000006b4 <+72>: ldr r3, [r4, #0] //czyli po 2 instrukcje na stworzenie obiektu na stosie
0x000006b6 <+74>: cmp r3, #1 0x000006b8 <+76>: beq.n 0x6c6 <main()+90> 0x000006ba <+78>: cmp r3, #2 0x000006bc <+80>: beq.n 0x6ca <main()+94> 0x000006be <+82>: cmp r3, #3 0x000006c0 <+84>: bne.n 0x6ce <main()+98> 0x000006c2 <+86>: add r0, sp, #12 0x000006c4 <+88>: b.n 0x6d0 <main()+100> 0x000006c6 <+90>: add r0, sp, #4 0x000006c8 <+92>: b.n 0x6d0 <main()+100> 0x000006ca <+94>: add r0, sp, #8 0x000006cc <+96>: b.n 0x6d0 <main()+100> 0x000006ce <+98>: add r0, sp, #16 // 13 instrukcji na obsłużenie 4 if-else 0x000006d0 <+100>: ldr r3, [r0, #0] 0x000006d2 <+102>: ldr r3, [r3, #0] 0x000006d4 <+104>: blx r3 // 3 instrukcje na wywołanie funkcji wirtualnejTo gdzie są te straszne koszta 'virtual'?
[1] Dump of assembler code for function foo::f(): 0x00000670 <+0>: ldr r0, [pc, #4] ; (0x678 <foo::f()+8>) 0x00000672 <+2>: b.w 0x3b4 <uart_print(char const*)> 0x00000676 <+6>: nop 0x00000678 <+8>: lsrs r7, r3, #18 0x0000067a <+10>: movs r0, r0