이 C ++ 코드에서 여기서 무슨 일이 일어나고 있습니까?
누구 든지이 C ++ 코드에서 무슨 일이 일어나고 있는지 설명해 주시겠습니까? Linux에서 잘 실행되고 실행됩니다.
#include <iostream>
using namespace std;
int main = ( cout << "Hello world!\n", 195 );
숫자 "195"는 x86의 RET 급 코드입니다.
C ++ 컴파일러 (제 경우에는 gcc)가 "main"이 "메인"이라고 할 수 없다는 인식 할 수 없습니다. 컴파일러는 "주"기호가있는 것이보고 함수를 참조 가정합니다.
C ++ 코드
int main = ( cout << "Hello world!\n", 195 );
파일 범위에서 변수를 초기화하고 있습니다. 이 초기화 코드는 C / C ++ 환경이 메인 ()을 호출하기 전에 실행됩니다. "cout"초기화 후에 실행됩니다. 초기화는 "Hello, world! \ n"을 인쇄하고 변수 "main"의 값을 195로 설정합니다. 모든 초기화가 이후 C / C ++ 환경은 "main"을 호출합니다. 프로그램은 "main"주소에 RET부터 (코드 195)를 넣었 기 때문에 즉시 반환됩니다.
샘플 GDB 출력 :
$ 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.
유효한 C ++ 프로그램이 아닙니다. 실제로 "Hello World"를 인쇄 한 후 Mac OSX에서 충돌이 발생합니다.
디스 어셈블리 쇼 main
는 정적 변수이며 이에 대한 이니셜 라이저가 있습니다.
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)
"Hello World"가 인쇄되는 이유는 무엇입니까?
"Hello World"가 출력되는 이유 main
는 정적 정수 변수 인의 초기화 중에 실행되기 때문 입니다. 정적 이니셜 라이저는 C ++ 런타임이 main()
. 이 경우 충돌이 발생 main
합니다. 유효한 함수가 아니기 때문에 실행 파일의 데이터 섹션에 정수 195 만 있습니다.
다른 대답은 유효한 명령 ret
이며 Linux에서 잘 실행 표시 섹션이 기본적으로 실행 불가능으로하기 때문에 OSX에서 충돌을 나타냅니다 .
C ++ 컴파일러가 main ()이 함수가 아니라고 링커 오류로 중지 할 수없는 이유는 무엇입니까?
main()
C 연결이 있으므로 링커는 기호 유형 차이를 알 수 없습니다. 우리의 경우 _main
데이터 섹션에 있습니다.
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
법적 프로그램은 아니지만 진단이 필요한지 아니면 정의되지 않은 행동인지에 대해서는 표준이 약간 모호하다고 생각합니다. (구현 품질 관점에서 진단을 기대합니다.)
Hello world를main
인쇄 한 후 전역 변수 (정수)를 195 값으로 설정합니다 . 실행하려면 main 함수를 정의해야합니다.
참고 URL : https://stackoverflow.com/questions/7660100/what-is-happening-here-in-this-c-code
'ProgramingTip' 카테고리의 다른 글
asp.net mvc 3 면도기보기에서 reportviewer 컨트롤을 어떻게 사용할 수 있습니까? (0) | 2020.12.04 |
---|---|
모듈에서 'before_save'콜백을 정의 할 수 있습니까? (0) | 2020.12.04 |
날짜에서 요일 이름을 얻는 방법은 무엇입니까? (0) | 2020.12.04 |
전송 속도와 비트 전송률의 차이점은 무엇입니까? (0) | 2020.12.04 |
루비 : 같은 객체를 가리 키지 않고 어떻게 변수를 복사 할 수 있습니까? (0) | 2020.12.04 |