C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[738] cout 의 재미있는 이야기.
이경문 [gilgil] 7114 읽음    2008-02-14 13:12
출처 : http://www.gilgil.co.kr/bbs/view.php?id=lecture&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=641

-------------------- cpp code --------------------
#include "iostream.h"
void main()
{
        char *gilgil = "gilgil";
        char *babo = " babo\r\n";
        char *gilgil_babo = "gilgil babo\r\n"

        cout << gilgil_babo;                 // (1)
        cout << gilgil; cout << babo;        // (2)
        cout << gilgil << babo;              // (3)
        return;
}

(1), (2), (3) 전부 동일한 출력을 하고 있으나, 구동 방식은 다음과 같이 전부 다릅니다.

-------------------- assembly pseudo code --------------------
(1) cout << gilgil_babo;
        push dword ptr "gilgil babo";
        push dword ptr [std::cout]
        call std::basic_ostream
        add esp, 0x08

(2) cout << gilgil; cout << babo;
        push dword ptr "gilgil"
        push dword ptr [std::cout]
        call std::basic_ostream
        add esp, 0x08
        push dword prt "babo"
        push dword ptr [std::cout]
        call std::basic_ostream
        add esp, 0x08
       
(3) cout << gilgil << babo;
        push dword ptr "babo"
        push dword ptr "gilgil"
        push dword ptr [std::cout]
        call std::basic_ostream
        add esp, 0x08                   <--- "gilgil" 먼저 제거
        push eax                        <--- [결론2] 증거
        call std::basic_ostream
        add esp, 0x08                   <--- "babo" 나중에 제거

[결론1]
<< 연산자는 인자(parameter)를 2개 가집니다.
하나는 실제 인자(먼저 push)이고 다른 하나는 cout 포인터(나중에 push)이죠.
(엄격히 따지면 cout 포인터는 메소드 call에 있어서 this 로 봐야 합니다)

<< 연산자의 수행은 함수 입장에서 봤을 때에는
cdecl calling convention이며(파라미터를 오른쪽에서부터 거꾸로 넣는다)
연속하는 << 연산자의 수행의 우선순위는 left-to-right 입니다(왼쪽부터 먼저 처리한다).
이를 헷갈리면 안됩니다!!!
즉, 함수 call을 위해 스택을 이용한 파라미터를 넘기는 방식은 cdecl이고
<< 를 수행하는 순서는 "gilgil"(왼쪽)부터 먼저 처리하고 나중에 "babo"(오른쪽)를 처리한다는 뜻입니다.

(3)번을 보면 언뜻 "babo"를 먼저 처리하고 "gilgil"을 나중에 처리하는 것처럼 보일 수 있지만
call std::basic_ostream이 이루저 지고 나서 esp에 0x08값을 빼어 내는 것을 보면
"gilgil"이 먼저 처리되고 나중에 "babo"가 처리되는 것을 알 수 있습니다.
처음 call에서는 쓰이지도 않을 "babo"를 제일 먼저 push하는 것을 보면
이는 operand와 operator를 postfix 변환을 하면서 stack상에서 처리하는 방식과 유사합니다.
("gilgil"과 "babo"가 하나의 함수내에서 한꺼번에 처리되는 게 아니다).

[결론2]
연속하는 << 연산자를 사용하는 경우 std::basic_ostream를 call하기 이전에
[std::cout]의 값을 push하지 않고 eax를 push하는 것을 보면
std::basic_ostream의 result는 cout의 pointer로 eax 레지스터에 저장이 되고
이 값(eax)이 다시 활용되는 것을 볼 수 있으며
이는 Compiler 기본적인 최적화의 한 방법으로 보여 집니다.
재미있네요. ^^

C코드로 해석해 본 gilgil의 쉽게 풀어 쓰는코드 ~~~
-------------------- gilgil(?) pseudo code --------------------
extern ostream *cout;

ostream *basic_ostream(ostream *cout, char *data)
{
        // 주절주절 알아서 일을 함...
        return cout;
}

void main()
{
        char *gilgil = "gilgil";
        char *babo = " babo\r\n";
        char *gilgil_babo = "gilgil babo\r\n";

        basic_ostream(cout, gilgil_babo);                       // (1)
        basic_ostream(cout, gilgil); basic_ostream(cout, babo)  // (2)
        basic_ostream(basic_ostream(cout, gilgil), babo);       // (3)
        return;
}

[테스트환경]
Borland C++Builder 5

[개인적인 결론]
C++에서 operator overloading은 코드를 쉽게 읽을 수 있도록 readability는 향상되지만
code optimization 부분에서 분석할 때에는 오히려 더 힘들다는 생각이 듭니다(헷갈려요).
그냥 평범한 메소드 call 이 속편하죠. ^^
김태선 [cppbuilder]   2008-02-14 13:37 X
좋은 실험 자료네요.

연산자는 함수의 다른 형태일 뿐입니다.
사람이 인식하기에 연산자가 직관성이 좋기 때문에, 연산자 오버로딩을 쓰는 거죠.
그런데 왜 gilgil....?
이경문 [gilgil]   2008-02-15 12:31 X
고등학교때 매점에서 제일 인기 있었던 빵이름입니다.
지금은 엄청 후회하고 있습니다.
공개석상에서 다른 분들이 저의 닉을 부를때
"길길이님", "길길님" 하면
뉘앙스가 너무 거시기해서...

"제임스", "촬리" 이런거하고 너무 비교가 되요. ㅠㅠ
김태선 [cppbuilder]   2008-02-15 13:13 X
닉에 관한 재미있는 이야기네요

좋은 글 잘 봤습니다. ^^
이경문 [gilgil]   2008-02-16 11:43 X
재미있는 얘기가 아니고
개인적으로는 슬픈 얘기에요. ㅠㅠ

+ -

관련 글 리스트
738 cout 의 재미있는 이야기. 이경문 7114 2008/02/14
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.