What is going on here in this C ++ code?

Can someone explain what is happening in this C ++ code. It compiles and works great on Linux.

#include <iostream> using namespace std; int main = ( cout << "Hello world!\n", 195 ); 
+59
c ++
05 Oct 2018-11-11T00:
source share
4 answers

The number "195" is the x86 RET command code.

The C ++ compiler (gcc in my case) cannot recognize that "main" was not declared as a function. The compiler only sees that there is a main character, and assumes that it refers to a function.

C ++ code

 int main = ( cout << "Hello world!\n", 195 ); 

initializes the variable in the file area. This initialization code is executed before the C / C ++ environment calls main (), but then initializes the "cout" variable. Initialization prints "Hello, world! \ N" and sets the value of the variable "main" to 195. After initialization is complete, the C / C ++ environment makes a call to "main". The program immediately returns from this call because we placed the RET instruction (code 195) at the address "main".

GDB output example:

 $ gdb ./a (gdb) break _fini Breakpoint 1 at 0x8048704 (gdb) print main $1 = 0 (gdb) disass &main Dump of assembler code for function main: 0x0804a0b4 <+0>: add %al,(%eax) 0x0804a0b6 <+2>: add %al,(%eax) End of assembler dump. (gdb) run Starting program: /home/atom/a Hello world! Breakpoint 1, 0x08048704 in _fini () (gdb) print main $2 = 195 (gdb) disass &main Dump of assembler code for function main: 0x0804a0b4 <+0>: ret 0x0804a0b5 <+1>: add %al,(%eax) 0x0804a0b7 <+3>: add %al,(%eax) End of assembler dump. 
+68
05 Oct 2018-11-11T00:
source share

This is not a valid C ++ program. In fact, it crashes for me on Mac OSX after printing "Hello World".

The demo shows that main is a static variable, and there are initializers for it:

 global constructors keyed to main: 0000000100000e20 pushq %rbp 0000000100000e21 movq %rsp,%rbp 0000000100000e24 movl $0x0000ffff,%esi 0000000100000e29 movl $0x00000001,%edi 0000000100000e2e leave 0000000100000e2f jmp __static_initialization_and_destruction_0(int, int) 

Why is he typing "Hello World"?

The reason you see the "Hello World" printout is because it starts during the static initialization of main , a static integer variable. Static initializers are called before the C ++ environment even tries to call main() . When this happens, it will work, since main not a valid function, there is only an integer 195 in the data section of the executable file.

Other answers indicate that this is a valid ret statement, and it works fine on Linux, but it crashes on OSX because by default this section is flagged as non-executable.

Why can't the C ++ compiler say that main () is not a function and stops with a linker error?

main() has a C connection, so the linker cannot distinguish the type of characters. In our case, _main is in the data section.

 start: 0000000100000eac pushq $0x00 0000000100000eae movq %rsp,%rbp ... 0000000100000c77 callq _main ; 1000010b0 0000000100000c7c movl %eax,%edi 0000000100000c7e callq 0x100000e16 ; symbol stub for: _exit 0000000100000c83 hlt ... ; the text section ends at 100000deb 
+39
Oct 05 '11 at 10:52
source share

This is not a legal program, but I believe that the standard is a bit ambiguous regarding the need for diagnostics or undefined behavior. (In terms of implementation quality, I would expect diagnostics.)

+5
05 Oct '11 at
source share

It will set the global variable main (integer) to 195 after printing Hello world. You still need to define the main function for its execution.

+1
Oct 05 2018-11-11T00:
source share



All Articles