Trying to provide a more general answer that would hopefully complement this answer linked in the comments.
To those who are unsure, the .rodata
section in an executable contains all read-only variables and constants with a global scope (i.e. will be defined for the entire duration of the program's execution) although the lines are becoming a little blurry and there are exceptions to the rules which are not actually enforced, the .rodata
section usually hold all global and static variables that are read only. This is obviously the reason the strings you defined are there.
Although your code does not directly define any constructs except those few string literals, the .rodata
section will hold all data deemed globally scoped and read-only by the compiler and linker, regardless of whether it was defined in your code or an additional variable/object your program uses explicitly or implicitly.
Now to your question; I mentioned additional objects can be explicitly and implicitly defined in your code, without you actually writing them. One explicit example is all the code #include
ed in your program (cstdio
in this case). Code implicitly included in your program is, for example, the code GCC adds that wraps and calls your defined main
function and handles different operating system interfaces (setting up functions related stdin, stderr, stdout) as well as set up and teardown of program objects (that code is where globally scoped objects are initialized by calling their constructor in C++).
Although this is explained in depth in the linked answer, the actual values (1
and 2
) appear to be for a constant defined by GCC's init.c
:
const int _IO_stdin_used = 0x20001;
That file is part of GCC's initialization code mentioned above, and is used to control the version of a input/output library GCC implements input/output in programs with.
it's worth noting that an hex-dump will help increase confidence in whether that is indeed the reason for the additional bytes you're seeing, as well as following the compilation and linking process, of course
A difference worth mentioning between your example and the one in the SO question if the 14 zero bytes, which are of course padding to a boundary of 16 bytes, which is something compilers often do to optimize for execution time. Replacing the -O3
with -Os
(optimize for size) will probably drop the 14 null bytes, although that is not guaranteed and may depend on the version of GCC you're using.