Why does using C ++ iterators significantly increase code size compared to at () or indexing?

I was looking for new C ++ language features, such as iterators on embedded systems (16KB SRAM and 64KB flash memory, Cortex M4) and hit the amazing roadblock. Why are iterators really so monstrously large? I got the impression that they are basically some kind of pointer arithmetic or indexing. Is STL some kind of unexpected code?

They use Kinetis Design Studio on windows with the toolchain gcc-arm-none-eabi-4_9 from here , using the following flags.

arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fsingle-precision-constant -flto -g3 -I"../Sources" -I"../Includes" -std=gnu++11 -fabi-version=0 -std=c++11 -MMD -MP -MF"Sources/System.d" -MT"Sources/System.o" -c -o "Sources/System.o" "../Sources/System.cpp" 

ITM_SendChar just takes one char and puts it in a register.

 std::string input = "Oh hai there! :D\n"; #ifdef char_array // .text 7352 // .data 376 // .bss 236 for(int i = 0; i < input.size(); i++) ITM_SendChar(input[i]); #endif #ifdef char_at // .text 7392 // .data 376 // .bss 236 for(int i = 0; i < input.size(); i++) ITM_SendChar(input.at(i)); #endif #ifdef char_itterator // .text 39744 // .data 384 // .bss 252 for(char some_char : input) ITM_SendChar(some_char); #endif #ifdef char_itterator_auto // .text 39744 // .data 384 // .bss 252 for(auto some_char : input) ITM_SendChar(some_char); #endif #ifdef char_itterator_auto_no_copy // .text 39744 // .data 384 // .bss 252 for(auto& some_char : input) ITM_SendChar(some_char); #endif 
+6
source share
2 answers

One (or two) C ++ standard backwards was legal for iterators to be implemented using pointers. (To learn more about this, you can google "delete the wording of the affection"). Newer standards require more from iterators, for example, if you have two corresponding iterators in two containers of the same type, then replacing these two containers also requires replacing these two iterators (see N4527 23.2.1 footnote 9 to read it for yourself , if you want to). All this means that indexing into a container with indexes instead of iterators can certainly be more efficient. This is just something that is not supported for all standard container types ... And also, why using iterators increases the size of the code.

+1
source

The main difference between the [] operator and .at () is that .at () checks the bounds and throws an exception if the index goes out of bounds.

It looks like the standard library implementation that you are using is binding additional code for something when using an iterator. The only way to find the reason is to examine the linker map file for both versions and carefully examine the source code for the functions you are using, and possibly the generated assembly.

In general, if you want your code to be very small, you want to avoid using any standard library, because the functions there can take a lot of code and data with them. Even code that parses the command line in the format that main () expects can be quite large.

For comparison, try the following:

 const char *input = "Oh hai there! :D\n"; while (*input) ITM_SendChar(*input++); 
+3
source

All Articles