https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117630
--- Comment #5 from R. Diez <rdiez-2006 at rd10 dot de> --- I am trying to figure out why generic_category_instance and system_category_instance land in my ELF file even though nobody is apparently using them. Other similar objects, like io_category_instance, do not. So I did an "objdump --disassemble" on the ELF file and tried to manually follow all references to those 2 instances. generic_category_instance is being used by something related to __throw_system_error() and by system_error_category::default_error_condition, which then gets complicated. However, system_category_instance is apparently only being used by something related to __throw_system_error(). That is the disassembly of that function: 0008a280 <_GLOBAL__sub_I__ZSt20__throw_system_errori>: 8a280: b580 push {r7, lr} 8a282: 4a07 ldr r2, [pc, #28] @ (8a2a0 <_GLOBAL__sub_I__ZSt20__throw_system_errori+0x20>) 8a284: af00 add r7, sp, #0 8a286: 4907 ldr r1, [pc, #28] @ (8a2a4 <_GLOBAL__sub_I__ZSt20__throw_system_errori+0x24>) 8a288: 4807 ldr r0, [pc, #28] @ (8a2a8 <_GLOBAL__sub_I__ZSt20__throw_system_errori+0x28>) 8a28a: f004 f8e5 bl 8e458 <__aeabi_atexit> 8a28e: 4a04 ldr r2, [pc, #16] @ (8a2a0 <_GLOBAL__sub_I__ZSt20__throw_system_errori+0x20>) 8a290: 4906 ldr r1, [pc, #24] @ (8a2ac <_GLOBAL__sub_I__ZSt20__throw_system_errori+0x2c>) 8a292: 4807 ldr r0, [pc, #28] @ (8a2b0 <_GLOBAL__sub_I__ZSt20__throw_system_errori+0x30>) 8a294: 46bd mov sp, r7 8a296: e8bd 4080 ldmia.w sp!, {r7, lr} 8a29a: f004 b8dd b.w 8e458 <__aeabi_atexit> 8a29e: bf00 nop 8a2a0: 20071120 .word 0x20071120 8a2a4: 0008e3cf .word 0x0008e3cf 8a2a8: 20071270 .word 0x20071270 <-- this is generic_category_instance 8a2ac: 0008e3d5 .word 0x0008e3d5 8a2b0: 2007126c .word 0x2007126c <-- this is system_category_instance I do not now much ARM assembly, but this looks like it is just registering the (empty) destructors with atexit(). I couldn't find any references to __throw_system_error() anywhere. I would venture that just the existence of generic_category_instance and system_category_instance is enough to pull in that generated code which calls atexit for the associated destructors. But then the same would probably happen with io_category_instance and others, unless the object files they live in do not get pulled at all. There is one thing I would like to understand. If nothing is calling __throw_system_error(), so that it does not get pulled into the ELF, and nothing else is using system_category_instance, shouldn't GCC and/or the linker be smart enough to discard the whole system_category_instance, including constructor and destructor code and/or data for it? Or does GCC believe that the atexit() call has side-effects (other than effectively destroying the object) and it does not eliminate that call then?