If I have a logging class which, in release mode, is empty, and has an ostream operator which does nothing. It more-or-less looks like this:
struct null_logger
{
template<typename T> inline null_logger& operator<<(T) { return *this; }
};
I've created a simple test and pasted the generated assembly below:
const char* foo()
{
return "hello";
}
int main()
{
int i = 0;
null_logger() << i << foo() << " this is a test";
return 0;
}
To be honest, I don't fully understand the assembly. As per suggestion from @Als, I have looked for call
statements, of which there are none. Is it therefore safe to assume that, in release mode, any calls to this ostream operator will be compiled out?
Here is the generated assembly, using g++ -O3 -S main.cpp
.file "main.cpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "hello"
.text
.p2align 4,,15
.globl _Z3foov
.type _Z3foov, @function
_Z3foov:
.LFB3:
movl $.LC0, %eax
ret
.LFE3:
.size _Z3foov, .-_Z3foov
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB4:
xorl %eax, %eax
ret
.LFE4:
.size main, .-main
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.globl __gxx_personality_v0
.string "zPR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x6
.byte 0x3
.long __gxx_personality_v0
.byte 0x3
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB3
.long .LFE3-.LFB3
.uleb128 0x0
.align 8
.LEFDE1:
.LSFDE3:
.long .LEFDE3-.LASFDE3
.LASFDE3:
.long .LASFDE3-.Lframe1
.long .LFB4
.long .LFE4-.LFB4
.uleb128 0x0
.align 8
.LEFDE3:
.ident "GCC: (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.string "Ospwg"
.section .note.GNU-stack,"",@progbits