[C/C++] Template with value

Language/C/C++ 2015/04/28 22:10

#include <stdio.h>


template<int N> class A {

public:

        A() { a = N;}

        int a;

};


int

main() {

        A<10> *a = new A<10>();

        printf("%d\n", a->a);

        return 0;

}


type이 아니라, 변수 값을 전달할 수도 있다. 이 경우 장점은?

compile time에 값이 정해지므로 compiler가 code를 optimize할 수 있다.



예.


[ a. cpp ]

#include <stdio.h>


template<int N> class A {

public:

        A(int n) { mN = n; }

        void speak() {

                if (N > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

        }

        int mN;

};


int

main() {

        A<10> *a = new A<10>(10);

        A<2> *b = new A<2>(2);

        a->speak();

        b->speak();

        return 0;

}


<< objdump >>

...

        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (N > 5)

                        printf("I'm BIG\n");

   c: bf 00 00 00 00       mov    $0x0,%edi

  11: e8 00 00 00 00       callq  16 <_ZN1AILi10EE5speakEv+0x16>

                else

                        printf("I'm SMALL\n");

        }

  16: c9                   leaveq 

  17: c3                   retq   


...


        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (N > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

   c: bf 00 00 00 00       mov    $0x0,%edi

  11: e8 00 00 00 00       callq  16 <_ZN1AILi2EE5speakEv+0x16>

        }

  16: c9                   leaveq 

  17: c3                   retq   


...






[ b. cpp ]

#include <stdio.h>


template<int N> class A {

public:

        A(int n) { mN = n; }

        void speak() {

                if (mN > 5)

                        printf("I'm BIG\n");

                else

                        printf("I'm SMALL\n");

        }

        int mN;

};


int

main() {

        A<10> *a = new A<10>(10);

        A<2> *b = new A<2>(2);

        a->speak();

        b->speak();

        return 0;

}



<< objdump >>

...

        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (mN > 5)

   c: 48 8b 45 f8           mov    -0x8(%rbp),%rax

  10: 8b 00                 mov    (%rax),%eax

  12: 83 f8 05             cmp    $0x5,%eax

  15: 7e 0c                 jle    23 <_ZN1AILi10EE5speakEv+0x23>

                        printf("I'm BIG\n");

  17: bf 00 00 00 00       mov    $0x0,%edi

  1c: e8 00 00 00 00       callq  21 <_ZN1AILi10EE5speakEv+0x21>

  21: eb 0a                 jmp    2d <_ZN1AILi10EE5speakEv+0x2d>

                else

                        printf("I'm SMALL\n");

  23: bf 00 00 00 00       mov    $0x0,%edi

  28: e8 00 00 00 00       callq  2d <_ZN1AILi10EE5speakEv+0x2d>

        }

  2d: c9                   leaveq 

  2e: c3                   retq   


...


        void speak() {

   0: 55                   push   %rbp

   1: 48 89 e5             mov    %rsp,%rbp

   4: 48 83 ec 10           sub    $0x10,%rsp

   8: 48 89 7d f8           mov    %rdi,-0x8(%rbp)

                if (mN > 5)

   c: 48 8b 45 f8           mov    -0x8(%rbp),%rax

  10: 8b 00                 mov    (%rax),%eax

  12: 83 f8 05             cmp    $0x5,%eax

  15: 7e 0c                 jle    23 <_ZN1AILi2EE5speakEv+0x23>

                        printf("I'm BIG\n");

  17: bf 00 00 00 00       mov    $0x0,%edi

  1c: e8 00 00 00 00       callq  21 <_ZN1AILi2EE5speakEv+0x21>

  21: eb 0a                 jmp    2d <_ZN1AILi2EE5speakEv+0x2d>

                else

                        printf("I'm SMALL\n");

  23: bf 00 00 00 00       mov    $0x0,%edi

  28: e8 00 00 00 00       callq  2d <_ZN1AILi2EE5speakEv+0x2d>

        }

  2d: c9                   leaveq 

  2e: c3                   retq   

...




===============================================


위의 코드를 보면, template 의 value를 사용할 경우, 'if'문에서, 사용되지 않는 코드가 compile시 object에 반영되지 않고 삭제되어 버리는 것을 알 수 있다.

즉 compile time에 충분히 optimize되어 버린다. (if 문의 condition이 compile time에 결정될 수 있으므로...)

'Language > C/C++' 카테고리의 다른 글

[C/C++] Template with value  (0) 2015/04/28
[C/C++] sizeof array  (0) 2015/03/19
[Macro] '##' macro operator  (0) 2015/02/11
'malloc' and 'Segmentation fault'  (0) 2014/07/25
[GCC] Initialize array...  (0) 2014/07/25
[Linux] Using named pipe in linux (주의할 점)  (0) 2014/01/09
Trackback 0 : Comment 0

[Essay] 회사의 실적이 나빠지면 직원들이 더 바빠지는 현상.

Essay/General 2015/04/22 21:53

직장생활을 하다보면, 제목과 같은 현상을 경험할 수 있다.

이게 '일반적'이라고 말하기에는 근거가 부족하지만, 개인적으로는 위와 같은 경험을 많이 해 본거 같다.


왜 그럴까?

가장 쉽게 생각할 수 있는 것은, 회사의 고정비를 줄이기 위해서 인력을 감축시키기 때문일 것이다.

업무량은 변하지 않았는데, 일하는 사람이 줄어드니, 남은 직원들은 더 바빠진다.


그런데, 개인적인 의견으로, 이것보다 더 중요한 요인은 "살아남기 위해서 일을 벌리기 때문" 이라고 생각한다.

회사의 고위층은, 실적이 나빠지면 살아남기 위해서 실적을 만들어야 한다.

그리고, 보통 '실적'은 '기존에 해 오던 일을 잘 하는 것' 보다는 '새로운 일을 해 내는 것'이 더 높은 평가를 받기 마련이다.

그렇다보니, 소위 '윗선'에서 자꾸 새로운 일을 만들어 내게 된다.


생각하기에 따라서는, 긍정적인 시각으로 이런 현상을 바라볼 수 있겠지만, 난, 부정적인 측면이 더 많다고 생각한다.

회사의 실적이 안 좋아지고, 고정비를 줄여야 하는 상황이라면, 일을 만들어 내는 것 보다는, 기존 일들에 대해서 우선순위를 정하고 "선택과 집중"을 통해서 어디에 회사의 역량을 집중할 것인가를 판단하는게 더 중요한 일이 아니겠는가?


물론, '기존에 해 오던 일을 잘 하는 것' 보다는 '새로운 일을 해 내는 것'에 대해서 압도적으로 높은 평가를 하는 것이 이런 현상의 근본 원인이긴 하겠지만, 그것과 별개로, 위기상황이라면, 좀더 합리적인 선택 - 선택과 집중 - 을 해야하지 않을까?

그렇지 못할 경우, 아마도 회사는 더 빠른 속도로 몰락의 길을 걷게 될 것이라고 본다.



Trackback 0 : Comment 0

[GNUMake] GNUMake variable expansion - dependency section

Domain/Software 2015/03/19 21:51

[Makefile]

general_var:= my-value

target: dep1 dep2

    <do something> $(general_var)

위의 makefile이 단독으로 사용되는 경우는, 전혀 문제가 되지 않는다. 그렇지만, makefile이 서로 서로 include되는 등의 복잡한 system에서는

경우에 따라, 위의 makefile이 parsing된 이후, general_var 의 값이 다른 값으로 바뀌게 될 수도 있다.(include된 다른 make file에서...)

이럴 경우, 'target'의 command section이 수행될 때는 'general_var'가 이미 다른 값으로 치환된 이후이기 때문에, 기대와 다른 동작을 하게 될 수 있다.

('blog의 variable expansion at command section on GNUMake 참조)

이것을 막기 위해서는 아래와 같은 형태로 make file을 구성해야 한다. 


[Makefile]

general_var:= my-value

target: private_var := $(general_var)

target: dep1 dep2

    <do something> $(private_var)

위의 makefile은, makefile이 parsing되고 target을 만들기 위한 rule이 수행되기 전에 아래와 같은 상태가 된다.


[Makefile]

general_var:= my-value

target: private_var := my-value

target: dep1 dep2

    <do something> $(private_var)


따라서, target 의 command section이 수행되기 전에, dependency section이 수행되면서 private_var값이 my-value로 set 되고

target 의 command section은 기대했던 'my-value' 값을 가지고 수행된다.

단, 아래와 같은 syntax는 "*** commands commence before first target.  Stop." error를 발생시키니 주의해야 한다.

(즉 dependency section에서 variable assignment를 수행할 경우, command section과 함께 있으면 안된다.) 


general_var:= my-value

target: private_var := my-value

    <do something> $(private_var)



Trackback 0 : Comment 0
◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [94] : NEXT ▶

티스토리 툴바