c++에서 new는 연산자인가요, 함수인가요?
글쓴이: awdxawdx101 / 작성시간: 일, 2020/06/14 - 11:18오후
지금까지 "new연산자" 라면서 배웠습니다.하지만 어느날 어셈블리어를 보니까
Dump of assembler code for function main: 0x00000000004007f7 <+0>: push rbp 0x00000000004007f8 <+1>: mov rbp,rsp 0x00000000004007fb <+4>: push rbx 0x00000000004007fc <+5>: sub rsp,0x18 0x0000000000400800 <+9>: mov edi,0x4 0x0000000000400805 <+14>: call 0x4006b0 <operator new(unsigned long)@plt> ...라고 되어있었습니다.
new 외에도 "<<"도 call을 이용하고, 오히려 함수인줄 알았던 cout이 "<<"의 인자로 들어가고..
연산자 오버로딩 때문에 call로 되는걸까요...?함수의 정의가 뭐냐고 물어보신다면 저렇게 call을 이용하면 함수라고 알고있습니다.
Forums:
...
> 함수의 정의가 뭐냐고 물어보신다면 저렇게 call을 이용하면 함수라고 알고있습니다.
이건 어셈블리어를 볼 때의 이야기이고요. (아니 정확하게 말하면 어셈블리에서는 "함수"의 개념 자체가 모호합니다. CPU에 그냥 아무 주소나 던져주고 call 명령을 내리면 CPU는 충실하게 스택에 현재 주소를 push하고 해당 주소로 점프할 테니까요. 그냥 사람이 이해하기 편하게 "이 부분은 함수, 여기는 그냥 branch target" 하는 거죠.)
기본적으로 C/C++과 어셈블리는 다른 언어입니다. 그러니까 당연히 1-1 대응이 안 됩니다.
new는 C++에서는 연산자이지만, C++에서도 operator overloading을 하면 거의 모든 연산자를 함수처럼 사용할 수 있고, 이게 십중팔구 어셈블리에서 함수를 부르는 것으로 매핑이 됩니다. ("십중팔구"이지 꼭 그러라는 법은 없습니다. 컴파일러가 최적화를 해서 함수콜을 없애 버릴 수도 있고 아예 해당 부분의 코드가 통째로 날라갈 수도 있습니다.)
감사합니다. 그럼 <<도 그렇고 연산자라고 부르는게
감사합니다. 그럼 <<도 그렇고 연산자라고 부르는게 맞는건가요?
...
네
연산자입니다. 함수이기도 합니다.
연산자입니다. 함수이기도 합니다.
1)
cout
은<iostream>
헤더에서 선언하는ostream
객체 인스턴스입니다. 함수가 아닙니다.2)
<<
는 물론 binary operator입니다. C언어에서는 left shift operator였지요.3)
cout << X
와 같은 표현식은, C++17 16.5.2에 따라operator<<(cout, X)
혹은cout.operator<<(X)
와 같이 해석되어, operator function을 호출하게 됩니다.구체적으로 어떤 함수가 호출되는지는 16.3.2 및 16.3.3을 참조해야 합니다만, 까마득하니까 생략하지요. 대부분의 간단한 타입에 대해서는
basic_ostream
템플릿 클래스에 멤버 함수 형태로 선언되어 있고,string
의 경우는<string>
헤더에 비멤버 형태로 선언되어 있습니다.cout << "hello world"
cout << "hello world"
->
<<(cout, "hello world")
연산자 맞아요.
연산자 맞아요.
나눗셈기가 없는 ARM 컴파일 하면 % 연산자도 함수 call 합니다.
어셈블리어 수준의 call과 언어에서 정의하는 연산자는 별개의 개념입니다.
----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라
why not both?
why not both?
함수이기도 합니다.
https://en.cppreference.com/w/cpp/memory/new/operator_new
new 연산자를 사용할 때마다 operator new라는 이름의 allocation function이 불리는 형태이지요.
operator new는 기본적으로는 std에 제공되는 것이 호출됩니다만, 프로그래머가 전역 혹은 클래스 멤버 형태로 정의하여 덮어씌워 버릴 수도 있습니다.
오퍼레이터는 함수의 syntactic sugar 에
오퍼레이터는 함수의 syntactic sugar 에 불과할까요?
그것은 스팩에 대한 구현 문제입니다.
그것은 스팩에 대한 구현 문제입니다.
언어 스팩에서 연산자라고 정의해도 언어 구현에서 함수를 호출 할 수 있지요.
예를들어 + 연산사는 언어 스팩에 연산자입니다. 그리고 해당 언어의 컴파일러가 이 연산자를 바로 "ADD"라는 어셈블리어로 바꿀 수 있습니다. 그런데 어떤 아키텍처에서 "ADD"라는 명령어를 지원하지 않는다면 함수 콜 형태로 바꿔서 + 연산자의 동작을 구현해야 합니다.
----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라
맞는 말씀이십니다.
맞는 말씀이십니다.
예컨대 말씀하신 대로 나눗셈 명령이 없는 아키텍처에서 정수 % 연산자의 실행은 함수를 호출하는 것으로 구현될 수 있지요.
나눗셈 명령이 있는 아키텍처에서도 그럴 수 있고요. (일부러 그렇게 할 컴파일러 개발자는 없겠지만요)
하지만 new-expression이 allocation function (operator new 혹은 new[])을 호출한다는 것, 그리고 표준 C++ 라이브러리가 global allocation function에 대한 default definition을 제공해야 한다는 사실은 표준에 명시되어 있습니다.
구현의 재량이 아니라는 뜻입니다.
혹시 기억이 잘 안 나신다면 C++17 각각 8.3.4, 6.7.4 항목을 참조해 보시면 되겠습니다.
물론 allocation function이 new-expression의 기능을 전부 수행하는 건 아닙니다만, 그 핵심 기능 (dynamic storage 관리)를 담당하고 있다고 볼 수 있습니다. 프로그래머에게 allocation function을 직접 작성하여 대체할 수 있는 메커니즘을 제공하는 역할도 있지요.
댓글 달기