C++11에 대한 개인적인 스터디 글들입니다.

<개인적으로 공부한 내용들로, 내용이 완벽하지 않을 수 있습니다. 부족한 부분/틀린 부분에 대한 Comment 환영합니다.>


* [C++11] Type Inference : auto

* [C++11] unique_ptr

* [C++11] Variadic template

* [C++11] rvalue reference

* [C++11] Move semantics

* [C++11] Range based for loop


<계속 추가 예정입니다만. 언제 될지는 미정입니다.>


GCC 버전별 C++0x/C++11 지원 현황 : 링크

'프로그래밍 언어 > C/C++' 카테고리의 다른 글

[C++11] unique_ptr  (7) 2013.11.01
[C++11] Type Inference: auto  (4) 2013.11.01
c++11 스터디(목차)  (0) 2013.11.01
constructor/destructor에서 virtual method의 호출  (0) 2013.02.27
GCC 옵션 : version script  (0) 2012.08.14
[C++] new는 null을 return하는가?  (1) 2012.01.17
Posted by 소혼
TAG C++11

댓글을 달아 주세요

간만에 블로깅을 하면서, 옛날에 설정해놨던 syntax highlighter관련 코드들이 스킨 변경으로 날라간걸 알게 되었다.


간만에 다시 설정하려고 하다가 CDN이 없을까 검색해 봤는데

이미 고마운 분이 간단하게 적용할 수 있는 스크립트를 제공하고 있었다.


적용 방법은 아래 주소를  참조.

http://kay.starian.kr/22


직접 적용을 원한다면,

Syntax highlighter 주소 : http://alexgorbatchev.com/SyntaxHighlighter/


Posted by 소혼

댓글을 달아 주세요

virtual키워드를 사용해 child 객체의 메소드들을 호출할 수 있다는 것은 C++을 공부한 사람이라면 다들 알고 있는 사항이다.

예를 들어, 아래의 코드에서는 child의 call method가 호출된다.

### c++

class parent {

public: 

    virtual void call();

};

class child : public parent {

public:

    void call();

};

int main()

{

    parent* p = new child;

    p->call(); // child의 call이 호출됨

}



그렇다면 child의 instance는 virtual로 선언된 메소드들에 대해서 항상 child를 호출하는가?

오늘 그렇지 않다는 것을 배웠다.


아래 예제를 보자.

### c++

#include <stdio.h>

static void externalCall();

class A
{
public:
    A() {
        printf("In Constructor A\n");
        call();
    }
    virtual ~A() {
        printf("In Destructor A\n");
        call();
        externalCall();
    }
    virtual void call() {
        printf("    Call A is called\n");
    }
    void callFromA() {
        printf(" > In %s \n", __func__);
        call();
    }
};

class B : public A
{
public:
    B() {
        printf("In Constructor B\n");
        call();
    }
    ~B() {
        printf("In Destructor B\n");
        call();
        externalCall();
    }
    void call() {
        printf("    Call B is called\n");
    }
};

static A* global;

static void externalCall()
{
    printf(" > In %s \n", __func__);
    global->call();
}

int main()
{
    A* local = new B;
    printf("In %s \n", __func__);
    local->call();
    local->callFromA();

    global = local;
    externalCall();

    delete local;
}



위 예제를 실행해보면 재밌는 결과를 얻을 수 있다.

In Constructor A ---- 1
    Call A is called
In Constructor B
    Call B is called
In main  ---- 2
    Call B is called
 > In callFromA
    Call B is called
 > In externalCall
    Call B is called
In Destructor B ---- 3
    Call B is called
 > In externalCall
    Call B is called
In Destructor A
    Call A is called
 > In externalCall
    Call A is called


1. 실행 결과에서 먼저 생성자의 호출 순서를 알 수 있다.

생성자의 경우 부모클래스(A)의 생성자가 호출된 후, 자식 클래스(B)의 생성자가 호출된다.

이 때, 자식 클래스의 생성자가 호출되기 이전에 부른 call method는 부모 클래스의 method가 호출됨을 알 수 있다.


2. main에서는 예측한 것과 같이 자식 클래스(B)의 method만이 호출됨을 알 수 있다.

설령, 부모클래스의 메소드를 거쳐서 호출하더라도(callFromA) 자식 클래스의 인스턴스이기 때문에 자식 클래스의 메소드가 호출된다.


3. destructor의 호출 순서는 생성자의 경우와 반대로 자식 클래스의 소멸자 -> 부모클래스의 소멸자 순으로 불린다.

이 때, 자식 클래스의 소멸자 안에서 호출한 call method는 자식 클래스(B)의 메소드가 불린 반면,

부모 클래스(A)의 소멸자 안에서는 자식 클래스(B)의 call method가 아닌, 부모 클래스(A)의 call method가 불린 것을 알 수 있다.


externalCall의 결과만 보면 자식 클래스(B)의 소멸자에서 불릴때와 부모클래스(A)의 소멸자에서 불릴때 다른 메소드가 불리게 된다는 것을 알 수 있다.

소멸자가 부른 외부 함수(또는 다른 클래스의 함수)가 이를 모르고 호출할 경우, 의도하지 않은 동작을 할 수도 있기 때문에,

소멸자가 호출하는 함수가 다시 자신의 메소드를 호출하지 않도록 주의할 필요가 있을 것 같다.


PS>

쓰고 보니 이미 Effective C++에서 다루고 있는 내용이었다.

다시 읽어봐야겠다. ㅠ_ㅠ


http://www.artima.com/cppsource/nevercall.html

Posted by 소혼

댓글을 달아 주세요

참고 : http://korea.gnu.org/manual/release/ld/ld-sjp/ld-ko_2.html
참고2: http://studyfoss.egloos.com/5254916
참고3: http://stackoverflow.com/questions/8129782/version-script-and-hidden-visibility

gcc 옵션 중 version script라는 게 있다는 사실을 알았다.

정확히는 ld 옵션이기 때문에 gcc에서 옵션을 줄 때는

-Wl,--version-script=파일 경로

의 형태를 가져야 한다.

참고2에서는 버전 관리를 위해 사용했으나,
버전 관리 뿐 아니라 심볼 개수를 줄이는 용도로도 활용이 가능한가 보다.

예컨데,

// t.c

int __attribute__((visibility("default"))) foo() { return 1; }
int bar() { return 2; }
int __attribute__((visibility("default"))) exported() { return 3; }

// t.lds

{
  global
: exported;
  local
: *;
};


gcc t
.c -Wl,--version-script=t.lds -fPIC -shared -o t.so && nm -D t.so
                 w _Jv_RegisterClasses
                 w __cxa_finalize
                 w __gmon_start__
00000000000004f2 T exported

visibility가 default인 값은 두개지만, 그중 exported만 보이는 것을 알 수 있다.

Posted by 소혼
TAG gcc, 옵션

댓글을 달아 주세요

디바이스 오리엔테이션:
http://bunhere.github.com/git-study/device/orientation/orientation.html
http://bunhere.github.com/git-study/device/orientation/motion.html

HTML5 Game Benchmarks
http://bunhere.github.com/HTML5-Game-Benchmarks/

media query
http://bunhere.github.io/html-study/mediaquery.html


Posted by 소혼

댓글을 달아 주세요

아무 생각없이 아래와 같은 CSS를 줬는데 동작하지 않아 대략 난감.

body {
    width: 480px;
    text-align: center;
    margin-left: 0;
    margin-top: 0;
}
 
한참을 헤매다 보니, HTML5로 동작하도록 <doctype html> 태그를 준 경우와 안 준 경우에서 차이가 발생했다.
찾아보니 아래와 같은 글을 발견
http://www.webmasterworld.com/html/3533864.htm 

자세한 이유는 더 분석해 봐야 할 것 같다.
일단 이유도 모르고 아래를 추가하니, 문제가 없어졌다.
h1, p { margin: 0px; }
 


Posted by 소혼
TAG HTML, margin

댓글을 달아 주세요

웹으로 간단한 프레젠테이션을 만들려고 했더니, html 태그를 쓰는게 무척 귀찮다는 걸 깨달았다.
물론 괜찮은 자바스크립트 유틸리티들이 있으면 쉽게 할 수 있겠지만, 원하는건 메모장 펴놓고 직접 고치는 거였는데...

xmp라는 태그가 있었으나, 해당 태그는 표준에서 제외되었다는 사실을 알았다.
https://www.w3.org/Bugs/Public/show_bug.cgi?id=12235

<pre plaintext=yes>...</pre> 와 같은 방법으로 지원하면 안되는건가? :(


Posted by 소혼
TAG HTML

댓글을 달아 주세요

작년에 malloc vs calloc이라는 글을 적었습니다.
그때는 급작스런 궁금증때문에 인터넷 검색+발번역을 했는데,
이번에는 new에 대해 신경쓰지 못했던 부분을 알게되었습니다.

흔히, new 나 malloc으로 메모리를 할당받고 난 후, 제대로 메모리가 할당되었는지 체크를 하지않는 경우가 많습니다.
하지만, 메모리가 부족한 상황은 얼마든지 나올 수 있으므로 체크를 해야 맞겠죠.

그렇다면, 어떻게 체크해야 할까요?
임베디드의 세상에서 malloc으로 메모리를 할당받은 후에는 null인지 확인하는 것이 보편적이라는 이야기를 들었습니다.

그렇다면 new는?
C++을 배울때 제대로 공부하신 분들은 이 질문의 답을 정확히 알것입니다.
네, new 는 0을 반환하지 않습니다. 일부러 그렇게 만들지 않는한 말이죠.(오퍼레이터 오버로딩)
대신 bad_alloc exception을 발생시킵니다.
따라서, 메모리할당 여부를 굳이 확인하려면, 아래와 같이 처리해야 합니다. (예제소스)
// bad_alloc example
#include <iostream>
#include <new>
using namespace std;

int main () {
  try
  {
    int* myarray= new int[10000];
  }
  catch (bad_alloc& ba)
  {
    cerr << "bad_alloc caught: " << ba.what() << endl;
  }
  return 0;
}

Posted by 소혼
TAG C++, new

댓글을 달아 주세요

  1. 몽상귀 2012.02.16 17:36 Address Modify/Delete Reply

    Note that you can specify that you want new to return 0 instead of throwing std::bad_alloc using the std::nothrow parameter:

    SomeType *p = new(std::nothrow) SomeType;

    http://stackoverflow.com/questions/550451/will-new-return-null-in-any-case

    즉, new 연산자를 수정하는 행위 없이 호출 할 때 저렇게 하면 된답니다. try-catch 쓰기 싫으시면 ..:D







오픈소스에 버그를 하나 등록했는데 아래와 같은 Comment를 받았습니다.


"this does not go to the .rodata section in the binary;

use static const char foo[] instead."

 이게 무슨 소린가 하고, 확인을 하기 위해 간단한 프로그램을 작성해보았습니다.



### c++

/* file: constchar.cpp
*
* gcc -S -O0 constchar.cpp -DCONST_POINTER
*/
#if defined(CONST_POINTER)
static const char* name = "hello";
#elif defined(CONST_ARRAY)
static const char name[] = "hello";
#else
static const char* const name = "hello";
#endif

int main()
{
return 0;
}


확인해보니 리뷰 comment대로

static const char* name = "Hello"; (이하 const_pointer)와 static const char name[] = "Hello"; (이하 const_array)

static const char* const name = "Hello"; (이하 const_pointer_const)

이 셋이 서로 다른 코드를 생성하는 것을 알 수 있었습니다.




먼저 .text 섹션을 보겠습니다.

main함수가 동일하기 때문에 위치만 다를뿐 동일합니다.

세 경우 모두, .rodata 섹션에 Hello 가 들어있습니다.

하지만 name(_ZL4name) 심볼의 경우,

const_pointer.s의 경우만 .data 섹션에 있고, const_array.s와 const_pointer_const.s의 경우에는 .rodata 섹션에 같이 있습니다.
생각해보면, const_pointer.s는 name의 값을 바꿀 수 있으니 당연히 .data 섹션에 변수로서 존재해야 합니다.
예를 들어 아래는 정상적인 코드입니다. static const char* name = "Hello";
name = "changed"; 하지만 아래는 컴파일 에러가 납니다. static const char name[] = "Hello";
name = "changed"; 따라서 변경 불가능한 문자열을 만들려고 한다면, const char [] 또는 const char* const를 사용해야 합니다.

그럼 const_array.s와 const_pointer_const.s의 차이는 뭘까요?

const_array.s를 보시면 LC0 label이 없는 것을 알 수 있습니다.

const_array.s의 경우만 name이 직접 Hello를 가르키고 있습니다.

(결론)
상수형 문자열을 쓰고자 한다면 static const char foo[] = "XXX"; 형태가 낫습니다.

참고로 아래 링크는 C언어의 변수 선언시 저장되는 영역에 관한 것입니다.
http://wwww7.com/bbs/zboard.php?id=Study&page=1&sn1=&divpage=1&category=3&sn=off&ss=on&sc=on&select_arrange=headnum&desc=desc&no=57


'프로그래밍 언어 > C/C++' 카테고리의 다른 글

GCC 옵션 : version script  (0) 2012.08.14
[C++] new는 null을 return하는가?  (1) 2012.01.17
static const char* vs static const char []  (0) 2012.01.04
우분투에서 ccache로 컴파일을 빠르게...  (0) 2011.08.31
POD vs non POD  (0) 2011.08.07
memwatch  (0) 2011.05.24
Posted by 소혼

댓글을 달아 주세요

자꾸 까먹어서 인터넷 검색을 하는게 싫어서 정리합니다 -_-;

SHELL 명령어

.tables : 테이블 목록을 보여준다.

.schema [table_name] : CREATE문을 보여준다.


SQL 명령어

select * from sqlite_master;
:
Posted by 소혼
TAG sqlite3

댓글을 달아 주세요