누가 gtk가 객체 지향 적이라 할 수 있을까요...

onemind555의 이미지

하나도 안 객체 지향 적이더군요..

소스를 보니 함수 하나가 수백줄이나 되고 완전히 if 문의 남발로 되어가지고 못 알아 보겠는 왜 이걸 객체 지향 적이라고 하죠...

Prentice의 이미지

반칙이 맞다는 명시적인 근거는 없지 않나요..?

http://bbs.kldp.org/viewtopic.php?t=31533

권순선 wrote:
이에 앞으로는 어떤 글에 대해 글타래를 잠그어 달라는 답글이 5개 이상이면 게시판 관리자가 해당 글을 잠그도록 하겠습니다.

아무튼 boxing에 대해 궁금하시면 새 글을 여시는 것은 어떨까요..?

doldori의 이미지

CN wrote:
smalltalk는 reference type으로 모든 자료형이 구성되어 있습니다. 하지만 현재의 객체지향 언어의 대부분은 value type과 reference type 모두를 가지고 있습니다. 이유는 기본적으로는 성능에 대한 생각이 밑 바탕에 있습니다. 그래서 대부분의 언어에서 이 둘은 다른 문법체제를 가지고 다른 형태로 다루고 있습니다. 이런 두 가지 type에 대한 자세는 혼동의 여지와 함께 기능성의 제약을 일으켰다는 비판도 있습니다. 이것을 해결하기 위해서 나온 컨셉이 boxing / unboxing입니다.

boxing / unboxing 의 개념은 JAVA보다 C#에 더 잘구현되어 있다고 볼 수 있습니다. boxing / unboxing은 primitive type을 wrap해주는 것이라는 것보다는 value type과 reference type 간의 가교 역활을 해줍니다. 자바에서는 value type는 primitive type이기 때문에 제한적인 boxing 과 unboxing이 사용된다고 할 수 있습니다.


저는 Smalltalk, C#, Java를 모릅니다만 boxing이라는 것은 매우 흥미로운 개념이군요.
제가 잘 이해했나 모르겠습니다만 사용자 정의형, 내장형 모두 reference 형을
기초로 한다는 말씀 같습니다. 이것이 언어 자체에 정의되어 있어서 autoboxing
이라는 말이 나오는 것 같고요. 제가 이해한 것을 C++로 표현해 봤는데 맞는지
모르겠습니다. CN님은 C++도 아실 테니 한 번 봐주시지요.
class Object
{
public:
    virtual ~Object() { }
    virtual void doSomething() = 0;
};

class IntValue : public Object
{
public:
    IntValue(int i) : i_(i) { }
    operator int&() { return i_; }
    void doSomething() { }
private:
    int i_;
};

class LongValue : public Object
{
public:
    LongValue(long l) : l_(l) { }
    operator long&() { return l_; }
    void doSomething() { }
private:
    long l_;
};

#include <typeinfo>

int main()
{
    Object& intV = *new IntValue(1);
    Object& longV = *new LongValue(2);
    try
    {
        dynamic_cast<LongValue&>(longV) = dynamic_cast<LongValue&>(intV);
    }
    catch (std::bad_cast&)
    {
        // must get here
    }
    dynamic_cast<LongValue&>(longV) = static_cast<long>(dynamic_cast<IntValue&>(intV));
    intV.doSomething();
    longV.doSomething();
}
죠커의 이미지

소스는 boxing / unboxing을 구현한게 맞는 것같습니다. C++에서 수많은 자료들에 대한 wrapper가 자동으로 만들 언어적인 제약이나 방법이 없고 reference를 받는 parameter나 reference type에 대한 대입에서 자동으로 boxing되지 않기 때문에 효용성이 떨어질 것 같습니다.

JAVA나 C#에서 모든 자료형이 reference type인 것은 아닙니다. JAVA는 기본타입 위주로 value type을 사용하여서 실속을 찾을려고 하고 있으며 C#의 경우 구조체는 value type 기반이며 value type인 기본 자료형들과 거의 유사하게 만들 기반이 마련되어 있습니다. C#쪽에서 boxing / unboxing이 더 유용하게 쓰일 수 있다고 생각합니다. C#에는 모든 value type이 boxing / unboxing 대상에 포함되니깐요.

akbar의 이미지

...

죠커의 이미지

다른 부분에 대해서는 특별한 이견은 없습니다. 오히려 오해의 폭이 좁아져서 기쁩니다.

akbar wrote:
더 정확히는
(boxing/unboxing 의 개념이 java 이전에 있었는지는 알 수 없으나)

순수 객체 지향언어는 primitive type 보다는 fundamental classes을 더 선호했기 때문에 Java가 처음이 아닐까 생각합니다.

akbar wrote:
GC 에 의해 관리되는 메모리 상에서 운영되는 시스템에서
주로 primitive type 에 대해, 스택 value type 의 값을 관리되는 메모리에 호환되는 어떤 값으로 만들어,
그 시작주소를 reference 로 하여, reference type 이 필요한 곳에서 개발자들이 좀 쉽게 쓸 수 없을 까 하는 생각에서 발전된 개념이다

고 보는 것이 좋을 것 같습니다.
이것은 동작만 놓고 봤을 때 C++ 에서 new 로 class 나 primitive type 를 heap 에 복사생성하는 것에 상응합니다.
이것을 C++ 에서, 특별히 boxing 이라고 부르며, 특별하게 보는 사람은 아무도 없습니다.
물론 boxing 을 단순히 이렇게만 볼 수는 없겠지만 이것에 대해서는 후술합니다.

그리고 GC 에 의해 관리되는 메모리 상에서 운영되는 시스템 이외에서 boxing 이라는 개념이 있든가요
Object Pascal 에 있든가요,
Perl 에 있나요, 아니면 Ada 에 있나요
이런 곳에서 boxing/unboxing 이 없다고 개발자들이 불평할 것 같지는 않습니다.
누군가 이것이 boxing/unboxing 과 비슷하다고 지적한다 할지라도 이들 개발자들은 boxing/unboxing 을 굳이 의식하지 않겠고 앞으로도 그럴 것입니다.
아무래도 boxing/unboxing 은 'GC' 라는 것을 사용하는 시스템에서만 의미가 있을 것 같습니다.

Object Pascal은 잘 모르지만 언급한 다른 언어들은 객체 지향과 밀접한 관계는 없을 것 같습니다.

Smalltalk 유저는 boxing / unboxing이 필요없을 것입니다. fundamental classes를 쓰는 객체 지향 유저는 괴리감이 없겠죠. C#은 primitive type 조차도 value type을 만드는 유일한 방법인 구조체(struct)로 구현되어 있어서 fundamental struct라고 부르는 것이 낫지 않을까 하는 생각도 해봅니다.

akbar wrote:
C++ 에서 value type을 polymophsm을 이용하기 위해 dynamic binding 을 해야할 정도라면
각 value type 을 설계할 때 인터페이스만 구현하는 공통의 기반클래스로 두고
이 기반 클래스로부터 상속하는 흔한 기법을 쓸 것입니다.

모든 자료형이 객체의 유연함을 가질 수 있다는 것을 알리기 위한 하나의 예시였습니다.

akbar wrote:
여기서 볼 것 같으면 boxing 이란 데이타를 모두 객체로 취급하려는 시도에서 출ㅤㅂㅑㄹ했을 것 같다는 생각도 듭니다.
실제로 boxing 개념을 사용하는 언어에서는 boxing 을 하면 그것은 객체가 되지 않겠습니까.

이 부분에 대해서는 크게 공감합니다.

htna의 이미지

boxing에 대해서는 예전에 스터디를 하면서 개념을 잡아서 다른 예제는 모르겠습니다만...
(java에서의 boxing에 대해서는 잘 모르겠습니다. java는 약 10년전에 학부때 공부하던것 말고는 이후로는 거의 볼 기회가 없어서. ^^;)
스터디를 통해서 짧게나마 C#을 공부하면서 boxing에대해 다음과 같이 느낍니다..
틀린부분 있으면 과감히 지적해 주시기 바랍니다.
제가 좀 모르는 부분이 많아서요. ^^;

C#에서 boxing에 대해서 크게 언급하는 이유는 다음과 같지 않나 합니다.
C#에서 모든 객체는 heap에 할당됩니다. 물론 이 heap에 할당된 객체는 GC에 의해서 관리되죠..
GC가 이 객체들을 관리하는 'managed object'를 다루는데 있어서 가장 큰 이슈가 되는 문제는 역시나 garbage collection입니다.
즉 언제 unused object의 garbage collection과 using object의 condensation(compression 이라고 해야하나..)을 하나 입니다.
아무래도 이 garbage collection이 시스템에 큰 영향을 주겠죠... (시간을 잡아먹을 테니깐요...)
이 garbage collection을 유도하는 심각하게 문제를 일으키는 주 원인중 하나가 temporary variable이다고 생각합니다.
(함수의 파라메터로 넘기거나, 결과로 넘어오거나, 계산과정의 중간값으로 사용되는, 등의...)
개념적인 접근을 하기 위해서 primitive object 또한 general object 와 동일하게 취급하고자 하는데. (언어적으로 간결하게 하기 위해서)
이런것들을 따로 처리하자니 그것도 애매하고, 그밖에 primitive object같이 사이즈는 작으면서 임시로 생성/삭제 되는 객체또한 garbage collection에 영향을 미칠테니깐요.
아무래도 임시로 사용되기 쉬운 객체들은 사이즈가 작을테고, 무수히 만들어지고 사라지죠, 그것들이 GC의 garbage collection의 frequence를 높이는 결과를 보이게 되고, 또한 이 object들이 사용되나 사용되지 않나를 끊임없이 체크해야 한다는 것이죠..

여기서부터 boxing이 나오게 된 배경이 되지 않나 봅니다.
그래서 가능한 garbage collection을 줄일 수 있는 방법으로 고안한게, 객체를 GC에 의해 관리되지 않게하고, stack에 직접 올리는 겁니다. primitive type처럼요.
크기가 작은, 더구나 primitive type이 하듯이, stack에 이러한 object를 올리더라도 시스템에는 무리가 없고 GC의 문제를 최소화 할 수 있을거라는 판단이죠.
더구나, 이렇게 임시로 사용되는 객체들을 다르게 관리할 경우 GC가 관리해야 하는 객체의 양이 훨씬(비약적으로 그러리라 생각합니다만) 줄어들 테니깐요.
아예 이렇게 진행하면서 primitive type도 같이 처리해버린듯 합니다. 프로그램 개념과 내부 로직/문법은 간결해지고, 성능은 비슷하리라 보구요..
(이러한 boxed object의 garbage collection은 stack의 pop명령으로 처리되겠죠. GC에 의해 참조되냐 아니냐 reference의 여부를 물을 필요도 없을테구요..)

이렇게 boxed object라는 개념(??)을 도입 하면서...
이 boxed object의 사용 판단 여부를 프로그래머에게 떠넘긴것 같습니다.
boxing, struct 라는 키워드들을 이용해서요...
즉 너희들이 GC의 성능을 boxing을 통해서 잘 조절해라, 하지만 그 boxed object의 크기가 커지면, 그때는 너희들 책임이다.
(객체를 복사하는 과정을 거쳐야 하니깐요. 만약 그 boxing되는 객체가 커지게되면 객체를 stack에 복사하는데 시간이 걸리겠죠.. 또한 stack의 크기가 커질것이구요.. 이는 프로그래머의 몱)

이렇게 방법을 정한 후에.
boxing 에 대해서 "Boxing is a way to wrap objects with primitive types over object types ..." 라고 정의하였다는...

아무래도 이런 스토리가, boxing의 배경이 아닌가 생각합니다.
머 원한다면 boxed object를 고려하지 않으면서 프로그램 할 수도 있겠지만..
그렇게되면 프로그램 성능에 크게 영향을 줄 듯 합니다...

이 boxing을 c++의 것과 비교한다는 것 자체가 좀 다른 개념을 서로 비교한다고느낌이 듭니다.
또한 boxing을 typecasting 과 같은 맥락에서 본다는 것도요...
어짜피 프로그램을 개발하는데 있어서 이 boxed object를 unboxed object와 상호 운용을 하기 위해서 typecasting을 이용하는게 젤 나은 방법이 아니었나 생각합니다.

음...
Java에서의 autoboxing은 흥미롭군요.
하지만, type casting이 다음과 같은경우에는 문제가 될 수 있지 않을까요 ?
class MyInt {
int _value;
int operator int() const;
unsigned int operator unsigned int() const;
};

MyInt mi;
int i1 = mi + 0xffffffff;
int i2 = mi - 0xffffffff;

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

죠커의 이미지

htna wrote:
C#에서 boxing에 대해서 크게 언급하는 이유는 다음과 같지 않나 합니다.
C#에서 모든 객체는 heap에 할당됩니다. 물론 이 heap에 할당된 객체는 GC에 의해서 관리되죠..
GC가 이 객체들을 관리하는 'managed object'를 다루는데 있어서 가장 큰 이슈가 되는 문제는 역시나 garbage collection입니다.
즉 언제 unused object의 garbage collection과 using object의 condensation(compression 이라고 해야하나..)을 하나 입니다.
아무래도 이 garbage collection이 시스템에 큰 영향을 주겠죠... (시간을 잡아먹을 테니깐요...)
이 garbage collection을 유도하는 심각하게 문제를 일으키는 주 원인중 하나가 temporary variable이다고 생각합니다.
(함수의 파라메터로 넘기거나, 결과로 넘어오거나, 계산과정의 중간값으로 사용되는, 등의...)
개념적인 접근을 하기 위해서 primitive object 또한 general object 와 동일하게 취급하고자 하는데. (언어적으로 간결하게 하기 위해서)
이런것들을 따로 처리하자니 그것도 애매하고, 그밖에 primitive object같이 사이즈는 작으면서 임시로 생성/삭제 되는 객체또한 garbage collection에 영향을 미칠테니깐요.
아무래도 임시로 사용되기 쉬운 객체들은 사이즈가 작을테고, 무수히 만들어지고 사라지죠, 그것들이 GC의 garbage collection의 frequence를 높이는 결과를 보이게 되고, 또한 이 object들이 사용되나 사용되지 않나를 끊임없이 체크해야 한다는 것이죠..

여기서부터 boxing이 나오게 된 배경이 되지 않나 봅니다.
그래서 가능한 garbage collection을 줄일 수 있는 방법으로 고안한게, 객체를 GC에 의해 관리되지 않게하고, stack에 직접 올리는 겁니다. primitive type처럼요.
크기가 작은, 더구나 primitive type이 하듯이, stack에 이러한 object를 올리더라도 시스템에는 무리가 없고 GC의 문제를 최소화 할 수 있을거라는 판단이죠.
더구나, 이렇게 임시로 사용되는 객체들을 다르게 관리할 경우 GC가 관리해야 하는 객체의 양이 훨씬(비약적으로 그러리라 생각합니다만) 줄어들 테니깐요.
아예 이렇게 진행하면서 primitive type도 같이 처리해버린듯 합니다. 프로그램 개념과 내부 로직/문법은 간결해지고, 성능은 비슷하리라 보구요..
(이러한 boxed object의 garbage collection은 stack의 pop명령으로 처리되겠죠. GC에 의해 참조되냐 아니냐 reference의 여부를 물을 필요도 없을테구요..)

언어의 명세는 대부분 구체적인 지점에서 이루어지진 않습니다. 구현을 생각해서 언어의 명세를 짜지는 않죠.

그리고 garbage collection의 주기가 짧아진다는 것은 큰 의미를 가지지 못합니다. 대부분의 gc는 임시객체에 대해서 삭제 우선순위를 높일 뿐이지 어느정도 gc가 채워질때까지는 삭제하지 않습니다.

갑자기 이 쓰레드가 boxing의 기술적인 면에만 집중하게 되는 것 같네요 :-)

htna의 이미지

CN wrote:
언어의 명세는 대부분 구체적인 지점에서 이루어지진 않습니다. 구현을 생각해서 언어의 명세를 짜지는 않죠.

물론 그렇습니다만, 이러한 것들이 boxing을 두드러지게 한 배경이 아닐까 생각한 겁니다.
물론 C#의 원 작자의 마음을 알 길이야 없겠죠..
^^

CN wrote:
garbage collection의 주기가 짧아진다는 것은 큰 의미를 가지지 못합니다. 대부분의 gc는 임시객체에 대해서 삭제 우선순위를 높일 뿐이지 어느정도 gc가 채워질때까지는 삭제하지 않습니다.

그만큼 frequently하게 생성되고 삭제되는 변수들이 GC개 금방 채워지게 하는데 영향을 미치는게 아닌지...
제가 잘못들었는지 모르겠지만, boxing을 사용하지 않고 프로그램을 작성하게 되면, 성능이 크게 나빠진다고 들은거 같은데요..
맞는말인지는 모르겠습니다.

아. 혹시 C#을 이용해서 실제 상용 application 작성하시는 분 없나요 ? 어느정도의 성능이 나오는지 매우 궁금하네요..
^^

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

정재윤의 이미지

boxing이 뭐 그리 대단한 개념이라고 이렇게 얘기가 되는지 모르겠네요. 또, 자바에서 처음으로 나온 개념이라니 ㅠ_ㅠ 눈물이 앞을 가릴 따름입니다. C의 예를 한번 보죠. 문자열과 숫자를 배열에 저장을 하려고 해봅시다. 간단히는
char *arr[2] = { "hello", (char *)10, };
여기서 배열에 들어가 있는데, 숫자일때는 직접 값이 들어가고, 문자열 일때는 그 문자열이 저장된 포인터가 들어가는 엽기적인 구성이 되면 프로그램짤때 힘들겠죠? 게다가 자바 같은 언어에서는 타입이 맞아야 코드가 돌아가니까... 그래서 10도 문자열 처럼 딴데다 저장하고 그 포인터만 배열에 집어 넣자라고 생각할 수 있습니다.

결국 GC때문에 필요하다고 하는건 좀 무리가 아닌가 싶네요. uniform한 형태로 접근이 가능하게 할려고 하는 거죠. 예를 들어서, 위의 예의 경우 좀 ad hoc하긴 하지만, 모든 reference/pointer는 보통 기계들에서 하위 두 bit가 00임을 감안할때 integer n은 2n + 1로 표시하면 별도의 boxing/unboxing없이도 숫자인지 문자인지 헷갈리지 않고 접근 할 수 있겠죠?

그리고, stack allocation이런거 얘기하는 분들도 있으신데 그거 별 관련 없습니다. Object o = new String("hello");
이랬다고 반드시 heap에 할당해야 하나요? 적당히 잘 분석하면 이건 stack에 집어 넣어도 되는 경우에는 stack에 할 수도 있는 겁니다. 어떻게 하는지는 열심히 컴파일러나 정적 분석하는 사람들이 열심히 하고 있습니다. 결국 프로그래머가 이런거 신경 쓰는건 삽질 되겠습니다.

CN wrote:

언어의 명세는 대부분 구체적인 지점에서 이루어지진 않습니다. 구현을 생각해서 언어의 명세를 짜지는 않죠.

그리고 garbage collection의 주기가 짧아진다는 것은 큰 의미를 가지지 못합니다. 대부분의 gc는 임시객체에 대해서 삭제 우선순위를 높일 뿐이지 어느정도 gc가 채워질때까지는 삭제하지 않습니다.

갑자기 이 쓰레드가 boxing의 기술적인 면에만 집중하게 되는 것 같네요 :-)


읽을 수록 CN님의 글에 딴지르 걸고 싶어지네요. "구체적인 지점" 이 뭡니까? 대부분이란 말은 어찌 그리 과감히 붙일 수 있는 것입니까? "GC주기가 짧아진다는 것은 " 왜 "큰 의미"를 가지지 못 하는건가요? GC의 방법이 얼마나 많은데 그렇게 단정하시나요? reference counting만 하더라도 당장에 그렇게 되는데요?

@잠궈야 할 주제에 글 써서 죄송합니다~

pynoos의 이미지

주제와는 딴 데로 흐르는 경향이 있지만, 조금만 자제하면 잠그지 않아도 주어 듣는 것이 많을 글타래가 될 것 같습니다.

살살 토론하셔요...

htna의 이미지

에궁. 일단..
이전글에, 제가 boxing 과 unboxing의 용어를 바꾸어 사용했던듯 합니다.
다음은 너무 간단한 예제일수도 있겠지만
PS:
혹 틀린부분 있음 과감히 지적부탁드립니다.
자잘한 문법이 틀렸을수 있습니다.
제가 c#을 스터디만 하고 실제로 사용해 보지는 않아서요..
^^;

int function ( int a, int b )
{
	return a + b;
}
void main()
{
	int sum = new int(0);
	for(int i=0; i<100; i++) {
		int a = sum;
		int b = i;
		sum += function(a , b);
	}
}

라는 함수가 있다손 칩시다. C++의 함수입니다.
이때 int 를 INT 라는 객체로 정의하여 다시 적용시킨다고 할때.
만약 boxing/unboxing 이라는 개념이 없다고 하죠.. (boxing을 사용 안한다고 이해해 주시길 바랍니다.)
그럼.

class INT {
	int _value;
	const INT operator +(const INT a) { return new INT(_value + a._value); }	// ****
	const INT operator -(const INT a) { return new INT(_value + a._value); }	// ****
	const INT operator =(const INT a) { _this = a._value; return this; }
}
INT function ( INT a, INT b )
{					// a, b 는 외부에서 생성된 객체이며, 이들의 주소는 stack에 입력됨
	return new INT(a + b);	// (a+b)를 리턴하기 위해 새로운 객체 INT를 생성 **
}
void main()
{
	INT sum = new INT(0);				// 새로운 INT 생성 **
	for(INT i=0; i<10000; i++) {		// 새로운 INT i 생성 **
		INT a = new INT(sum);			// 새로운 INT a 생성, sum의 값을 a에 기록 ****
		INT b = new INT(i);				// 새로운 INT b 생성, i의 값을 b에 기록 ****
		sum = sum + function(a , b);	// function에 파라메터를 넘기기 위해, a,b가 가리키는 주소를 stack에 복사하여 function에 전달
										// function 으로부터 리턴값이 넘어오기 위해 function으로부터 INT 생성됨 ****
										// function 으로부터 넘어온 값과 sum을 더하기 위한 중간변수로 새로운 INT 생성됨 ****
	}
}

다음과 같이 분석할 수 있을 것입니다.
여기서 임시로 생성되는 객체중 반복적으로 생성되는 것들은 **** 인 것들이 될 것입니다.
이때 총 생성되는 임시객체는 대략 (4 * 10000 + 2) = 40002 개가 되지 않을까 합니다.
이 반복문이 좀 커지게 되고, 이렇게 임시로 생성되는 임시객체들의 크기가 커지면 GC의 호출이 불가피하지 않을까 합니다.
(물론 b에서 new하는게 필요없다고 하실 수도 있겠지만, 머 결과는 비슷하리라 봅니다.)

이젠 boxing의 개념을 도입하겠습니다.
즉 sum만이 boxing에 의해 heap에 할당되는 객체이고, 나머지것들은 stack에 할당되는 것들입니다.

struct INT {
	int _value;
	const INT operator +(const INT a) { return INT(_value + a._value); }
	const INT operator -(const INT a) { return INT(_value + a._value); }
	const INT operator =(const INT a) { _this = a._value; return this; }
}
INT function ( INT a, INT b )
{					// a, b 는 스택을 통해 넘어옴
	return a + b;	// (a+b)를 리턴하기 위한 값을 stack에 기록
}
void main()
{
	INT sum = new INT(0);				// 새로운 INT 생성 **
	for(INT i=0; i<10000; i++) {		// 스택에 INT i 생성
		INT a = sum;					// 스택에 INT a 생성, unboxing을 통해 스택의 변수 a에 sum의 값 기록
		INT b = i;						// 스택에 INT b 생성, i의 값을 a에 복사
		sum = sum + function(a , b);	// function에 파라메터를 넘기기 위해 스택에 a,b의 값을 기록
										// function 으로부터 리턴값이 stack 으로 넘어오게 되고,
										// 이렇게 넘어온 값과 sum의 덧셈을 스택의 임시변수를 통하여 실행한 뒤 sum에 기록
	}
}

이경우로 보면,
실제로 heap에 생성되는 객체는 sum 한개 뿐이 됩니다. 즉 GC가 관리해야 하는 객체는 1개인셈이죠.
고로 GC의 부하를 줄이게 되는것 아닌가요. ?

물론 이는 아주 간단한 예제의 하나일 뿐이겠지만, 실제로 문제는 이보다 더 심각해지지 않을까 합니다.
우리가 알게모르게 사용하는 임시변수들이 의외로 (아주!!!) 많거든요.. 단지 자동으로 지워지기에 모르면서 지낼 뿐이죠...
아. 당연히 아시는것이겠지만, string의 경우는 워낙 크기를 가늠할 수 없는 놈이라 그런지. 아예 reference type으로 구분해 놓았군요...

PS:
좀 쓸데없는 내용이 길었습니다.
^^;

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

죠커의 이미지

정재윤 wrote:
boxing이 뭐 그리 대단한 개념이라고 이렇게 얘기가 되는지 모르겠네요. 또, 자바에서 처음으로 나온 개념이라니 ㅠ_ㅠ 눈물이 앞을 가릴 따름입니다. C의 예를 한번 보죠. 문자열과 숫자를 배열에 저장을 하려고 해봅시다.

boxing이 C/C++에서 의미없다는 말은 foundation classes를 사용하는 언어들에서 &과 *가 의미가 없다고 말하는 것과 비슷하게 들립니다. 눈 두개 가진 사람은 눈 하나를 가진 사람들의 마을에서는 이상한 사람입니다. 패러다임에 따른 관심사의 차이에 대해 실소를 하는 것은 과격한 반응입니다.

정재윤 wrote:
읽을 수록 CN님의 글에 딴지르 걸고 싶어지네요. "구체적인 지점" 이 뭡니까? 대부분이란 말은 어찌 그리 과감히 붙일 수 있는 것입니까?

언어의 스펙들을 읽어보세요. 스펙에서의 근거는 일반적으로 기술적인 부분보다는 논리적인 부분입니다. 지나치게 stack과 heap위주로 boxing을 보는 것은 주객이 바뀐 것이 아니냐고 지적하기 위해서 위의 글을 적었습니다. C/C++를 말씀하셔서 덧 붙여 본다면 C/C++의 스펙에서는 heap / stack등의 말은 나오지도 않습니다. 또 C/C++ 스펙을 만드는 사람이 컴파일러 모델을 마음 속에 담아 두고 있는지는 알 수 없지만 스펙에는 그 것을 표현하지 않았습니다. 언어의 스펙에서 구현의 방법은 1순위가 아닙니다.

정재윤 wrote:
"GC주기가 짧아진다는 것은 " 왜 "큰 의미"를 가지지 못 하는건가요? GC의 방법이 얼마나 많은데 그렇게 단정하시나요? reference counting만 하더라도 당장에 그렇게 되는데요?

상업적인 GC 중에서 어느 시점에 (공간이 얼마나 채워졌을때) 정리할 지 세팅 못하는 GC가 더 적을 것입니다. 많은 GC들은 한 수 더 떠서 명시적인 정리까지 지원하고 있습니다. (소프트웨어가 자원의 여유가 있을때 GC를 정리하게끔 돕는 것입니다.) 임시객체 하나가 만들어지고 소멸했다고 GC가 즉시 반응한다면 memory pooling을 사용하는 대신 (보너스로 reference couning도 되어있다고 합시다.) GC를 구입하시겠습니까? GC의 구현 방법과 상관없이 GC가 그렇게 부지런하게 움직이지 않을 것임을 정재윤님이 더 잘 알고 계실 거라 생각합니다.

정재윤의 이미지

CN wrote:

boxing이 C/C++에서 의미없다는 말은 foundation classes를 사용하는 언어들에서 &과 *가 의미가 없다고 말하는 것과 비슷하게 들립니다. 눈 두개 가진 사람은 눈 하나를 가진 사람들의 마을에서는 이상한 사람입니다. 패러다임에 따른 관심사의 차이에 대해 실소를 하는 것은 과격한 반응입니다.

제가 boxing이 C/C++에서 의미 없다는 얘길 한 적 전혀 없습니다. 저는 boxing/unboxing이라는 개념 자체를 C의 예에서 설명한 것 뿐입니다. 간단히 같은 일상의 예를 들어도 전혀 무방한 장면입니다.
제가 님의 글에 냉소적으로, 다소 과격하게 반응한 것은 간단한 개념을 대부분의 언어는 이렇다, GC에서 이러 이러하다라는 식의 구체적 근거가 없는, 불필요한 말로 설명에 별 도움이 되지 않는 얘길 하셔서 그랬습니다. 눈 두개 어쩌구 하는 언급은 전혀 적절하지 않는것 같습니다. 패러다임에 따라서 개념이 달라지나요?
스펙에 관한 님의 언급도 도저히 저의 상식으로는 이해가 가지 않는 군요. 스펙이 단순한 기계적 기술이 아닌 논리적 이유를 설명한다니.

CN wrote:

임시객체 하나가 만들어지고 소멸했다고 GC가 즉시 반응한다면 memory pooling을 사용하는 대신 (보너스로 reference couning도 되어있다고 합시다.) GC를 구입하시겠습니까? GC의 구현 방법과 상관없이 GC가 그렇게 부지런하게 움직이지 않을 것임을 정재윤님이 더 잘 알고 계실 거라 생각합니다.

그때 그때 따라 다른 겁니다. 그리고 "임시객체 하나 만들어지고 소멸할때 GC가 즉시 반응하는 기능 하나로", 제품 구매를 결정할 바보가 어디 있습니까? 님의 논리는 상용들 대부분은 GC가 그렇게 부지런 할 리가 없으니까, GC를 자주해도 임시객체를 바로 지우지 않는다 이런 얘기신가요? 그게 의미가 있을지 없을지는 상황에 따라 다른 거 아닌가요?
익명 사용자의 이미지

auto Boxing을 하는 이유가 무엇일까요?
1) int pOne = 1;
2) Integer oOne = new Integer(1);

2번은 아무래도 불편하죠?
String와 같이 Value Object로 사용될 놈들에게는
aotoBoxing이 되면 아무래도 편해서 아닐까요?

number, boolean 등을 Object로 만들고 Object의 value를
primitive와 연산해야 할경우가 생기면 정말 귀찮더군요.
더욱이 코드가 아주 지저분하게 만들게 되는거 같습니다.

불필요한 코드의 생성으로 가독성을 떨어 뜨리느니
알아서 autoBoxing을 해주면 깔끔하지 안을까요?

결국 autoBoxing은 사람과 친숙한 코드를 만들게 해주려고 고안된 개념이 아닐까요? primitive/Object에 상관없이 맘껏 먹어라 계산은 내가(VM) 한다.

akbar의 이미지

...

htna의 이미지

akbar wrote:
그래 보겠습니다. 전체적으로 내용이 오류투성이 입니다.
boxing 은 (주로) primitive type 에 대하여 GC가 관리하게끔 GC heap 에 올리는 것입니다. 스택에 올리는 것이 아닙니다.
boxed object 는 GC heap 에 생긴이상 reference의 여부를 반드시 물어야 합니다. 만약 어떤 컨테이너에 boxed object 를 담았는데 GC 가 boxed object 를 reference의 여부를 확인도 하지 않고 지운다면 큰일납니다.
boxed object 의 사용 판단 여부를 프로그래머가 아닌 GC 같은 시스템에 넘긴 것입니다. 그래서 프로그래머의 고민을 조금이지만 덜어 준 것입니다.

"이전글에, 제가 boxing 과 unboxing의 용어를 바꾸어 사용했던듯 합니다. "
하고 용어사용에 있어서 잘못되게 사용된거 같다고 먼저 언급하였었습니다.
님께서는 보질 못하셨는듯..

경우에따라 boxing/unboxing의 통괄적인 개념을 가리키고자 boxing이란 용어를 사용하면서도 문제가 있었던듯 싶네요.

akbar wrote:
잘못들으셨네요. (auto)boxing을 사용할 수록 overhead 는 커지는 것입니다.

왜 하필이면 (auto)boxing이 문제가 되는지 궁금해지네요..
님께서도 (auto)boxing을 가리키기 위해 용어를 사용한게 아니라, (auto)boxing이라는 process/방법 을 가리키기 위해 이 용어를 사용하셨죠.. ??

akbar wrote:
boxing 의 최종결과물은 GC 힙에 복사 생성된 객체의 포인터입니다. 이 최종결과물만 보았을 때 C++ 에서 boxing 에 대응하는 것을 억지로 찾다보니 그런것입니다.
거듭말하지만 boxing 이라는 과정은 (주로) primitive type 에 대해 (GC) heap 에 복사생성하는 작업입니다.
primitive type 을 GC heap 에 굳이 만드는 것 자체가 overhead 가 있게 되는 것이죠
따라서 boxing 을 사용하면 할수록 성능에 안좋습니다.

전반적인 내용은 맞습니다만, C#에 primitive type이란게 없습니다. 그점은 확실하죠...
결국 님이 말씀하시는 것은, boxing을 이용하게되면 각 primitive type에 해당하는 값을 heap에 생성하게 되니, 문제가 된다.
(경우에 따라) 기존의 방법처럼(?) stack에 생성해서 사용하는게 낫다 는 말과 어떤면에서는 같은 견해를 가지시는듯 하네요.
그예기가 unboxed object를 얘기하시는 건가요? 전 unboxed 객체 즉 struct 객체를 프로그래머가 알아서 잘 사용하여, 작성된 code에 따라 GC에 영향을 덜 주게 하고자 하는듯 하다는 의도로 먼저 말을 했었습니다만... 결과적으로 C# 사용에 따른 프로그램 성능 하락/향상의 책임을 부분적으로 프로그래머들에게 떠넘긴 결과가 된다는...

akbar wrote:
C++ 의 type casting 을 위와 같이 사용하는 것은 '그냥' 그렇게 하는 것입니다.
overflow 문제가 있을 것 같으면 응당 특별한 처리를 해주어야 할 것이구요.
C++ 의 type casting 은 위 예제코드와 같은 '원래 당연히 그런' 형변환 보다는
서로 다른 클래스간에 통신하는데 아주 훌륭하게 쓰일 수 있는 것이죠.
그렇다면 boxing 을 primitive type 과 객체간에 통신하는데에 쓰는 것과 닮지 않았습니까.

overflow 문제를 짚기위해서만 그 예를 사용한것이 아닙니다.
그러한 경우에 unsigned int로 캐스팅이 되느야 signed int로 캐스팅이 되느냐에 따라 overflow가 발생할 수 있기때문에,
때로는 autoboxing(용어 맞나요?) 을 사용하면서 컴파일러가 코드해석에 따른 애매모호한 지점이 생길 수 있다는 것을 지적하기 위해서 저 예제를 사용하였던 것입니다.
아무래도 제가 설명을 좀 부족하게 달았나 싶습니다.
예제를 좀 바꿔야 할 듯 하네요...
// int의 범위기 (-0x8fffffff ~ 0x8ffffffe) 까지이고, unsigned int의 범위가 (0 ~ 0xffffffff) 까지일때.
MyInt mi; 
unsigned int i1 = mi + 0x8ffffffe;  (1)
int i2 = mi - 0x8fffffff;  (2)
// 에서 mi 를 unsigned int로 auto unboxing을 하냐, 아니면 int로 auto unboxing 하냐에 따라 overflow가 발생할 수 있다고 예를 들어야 할 듯.
// 이러한 경우
unsigned int i1 = (unsigned int)mi + 0x8ffffffe;  (1)
int i2 = (int)mi - 0x8fffffff;  (2)

이건 맞나.. 요. ? 핵갈린다. @.@

akbar wrote:
혹시 C# 으로 프로젝트를 하실거면 불필요한 boxing 은 일어나지 않게 주의하기 바랍니다.

불필요한 boxing이 일어나게 하는것도 중요한 일입니다만, 그보다 근본적인 원인을 제공하는 unboxed object, 즉 객체 구현시 struct 과 class의 선택을 신중하게 하는게 더 중요하지 않나 생각합니다.
그 이후에야 struct로 정의된 object를 사용하는데 있어서 boxing이 되게 할지 그냥 stack에 객체를 놓고 사용하게 할지 를 주의해야 하는게 아닌가 생각합니다만...

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

익명 사용자의 이미지

내용하고는 관련없지만.
님 --> 누구누구님 or 누구누구씨로 하는게 좋지 않을까요?

바른말 고운말을 사용합시다.

익명 사용자의 이미지

내용하고는 관련없지만.
님 --> 누구누구님 or 누구누구씨로 하는게 좋지 않을까요?

바른말 고운말을 사용합시다.

에 한표

htna의 이미지

아...
타이핑을 길게하는게 귀찮아서. 그냥 '님' 이라고만 한 것입니다...
예전에 게임하면서 길들여진 습관이 남아서 고쳐지지 않고 있다는..
마우스 움직이랴, 키보드치랴 정신없죠. 한자라도 줄여야 한다는...
제가 게으른편이라. ^^;;;
'바른말 고운말'의 대상이 될줄은 생각지도 못했네요...
ㅡ.ㅜ

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

akbar의 이미지

...

voljin의 이미지

akbar wrote:
htna wrote:
overflow 문제를 짚기위해서만 그 예를 사용한것이 아닙니다.
그러한 경우에 unsigned int로 캐스팅이 되느야 signed int로 캐스팅이 되느냐에 따라 overflow가 발생할 수 있기때문에,
때로는 autoboxing(용어 맞나요?) 을 사용하면서 컴파일러가 코드해석에 따른 애매모호한 지점이 생길 수 있다는 것을 지적하기 위해서 저 예제를 사용하였던 것입니다.
아무래도 제가 설명을 좀 부족하게 달았나 싶습니다.
예제를 좀 바꿔야 할 듯 하네요...
// int의 범㎟?(-0x8fffffff ~ 0x8ffffffe) 까지이고, unsigned int의 범위가 (0 ~ 0xffffffff) 까지일때.
MyInt mi; 
unsigned int i1 = mi + 0x8ffffffe;  (1)
int i2 = mi - 0x8fffffff;  (2)
// 에서 mi 를 unsigned int로 auto unboxing을 하냐, 아니면 int로 auto unboxing 하냐에 따라 overflow가 발생할 수 있다고 예를 들어야 할 듯.
// 이러한 경우
unsigned int i1 = (unsigned int)mi + 0x8ffffffe;  (1)
int i2 = (int)mi - 0x8fffffff;  (2)

이건 맞나.. 요. ? 핵갈린다. @.@

헷깔리죠. 전체적으로 boxing 과 그에 따른 overhead 가 C# java 에서 어떤 의미를 가지는지 헤메시는 것 같네요
참고로
C# 이나 java 에서 포인터(참조)가 필요한 곳에 포인터를 넘길때 그 포인터는 스택에 있는 메모리를 가리켜서는 안된다.
이 의미를 생각해 보시기 바랍니다.
그리고 boxing 을 C++ 에서 '어떤 의미'를 찾으려고 하지 마세요. 부질없는 일입니다.

열심히 곁눈질 하고 있는데 akbar님의 이야기는 조금 포괄적이고 읽는 사람에게 많은 부분을 맡기는 것 같아서 헤매고 있습니다. 귀찮으시더라도 헤매고 있는 사람을 위해서 사례를 들어서 설명해주시면 좋겠네요. :oops:

죠커의 이미지

정재윤 wrote:
제가 님의 글에 냉소적으로, 다소 과격하게 반응한 것은 간단한 개념을 대부분의 언어는 이렇다, GC에서 이러 이러하다라는 식의 구체적 근거가 없는, 불필요한 말로 설명에 별 도움이 되지 않는 얘길 하셔서 그랬습니다. 눈 두개 어쩌구 하는 언급은 전혀 적절하지 않는것 같습니다. 패러다임에 따라서 개념이 달라지나요?

쓰래드에 있었던 글에 대한 대답으로 글을 구성했기 때문에 구성이 중구난방이 되었을 가능성이 있습니다. 하지만 쓰래드 전체를 읽어보았을때 짝이 안 맞는 글이 있는지 궁금하군요. 이번 쓰래드에서 나의 글은 처음 부터 끝까지 반론을 하고 있기 때문에 개념의 설명에 대한 도움이 안될겁니다.

패러다임에 대한 얘기는 저의 실수라는 것을 인정합니다. 구체적인 구현에 의존하지 않는 다는 말에 부정적으로 대답하셨길래 C#과 Java가 Unified type model을 체택하기 때문에 boxing / unboxing이 중요하다는 것에 대해서 반대하는 분이신 줄 알았습니다. 게다가 글의 첫부분의 눈물이 날 지경이라는 부분과 C언어 소스를 보았을때 C언어를 통해서 기술적으로 boxing / unboxing이 필요없다고 말할려는 분이신 줄 알았습니다.

정재윤 wrote:
스펙에 관한 님의 언급도 도저히 저의 상식으로는 이해가 가지 않는 군요. 스펙이 단순한 기계적 기술이 아닌 논리적 이유를 설명한다니.

언어의 스펙은 구체적인 구현에 의존 하지 않고 논리적으로 구성할려고 합니다. 이 부분에 대해서는 중복되는 이야기를 하게 되는 군요.

순환고리를 끊기 위해서 권유하자면 ISO C/C++ 표준을 읽어 보십시요.

정재윤 wrote:
그때 그때 따라 다른 겁니다. 그리고 "임시객체 하나 만들어지고 소멸할때 GC가 즉시 반응하는 기능 하나로", 제품 구매를 결정할 바보가 어디 있습니까? 님의 논리는 상용들 대부분은 GC가 그렇게 부지런 할 리가 없으니까, GC를 자주해도 임시객체를 바로 지우지 않는다 이런 얘기신가요? 그게 의미가 있을지 없을지는 상황에 따라 다른 거 아닌가요?

boxing / unboxing이 GC의 frequency가 증가할 가능성이 있다는 의견이 있었습니다. 그런 micro optimization에 focus를 맞추는 것이 실제 프로그래밍에 있어서 도움이 안된다고 생각해서 간단한 반론으로 이야기의 주제를 돌리길 원한 것입니다.

boxing / unboxing이 부분적으로 어느정도 부하를 만들지 생각하는 것 보다는 전체적인 프로그래밍이 표준에 맞고 논리적으로 맞는지 생각해보고 전체 프로그램을 만든 후에 프로파일링을 통해서 부하를 제거하는 것이 옳다고 믿고 있습니다.

htna의 이미지

akbar wrote:
헷깔리죠. 전체적으로 boxing 과 그에 따른 overhead 가 C# java 에서 어떤 의미를 가지는지 헤메시는 것 같네요

제가 설명을 붙이면서, "때로는 autoboxing(용어 맞나요?) 을 사용하면서 컴파일러가 코드해석에 따른 애매모호한 지점이 생길 수 있다는 것을 지적하기 위해서 저 예제를 사용하였던 것입니다." 라는 설명을 덧붙였습니다. 물론 그에 합당하는 정확한 예제를 들기가 쉽지 않다는 뜻으로 "핵갈린다" 고 한 것입니다.
다른쪽으로 엉뚱한 해석하시지 않아주셨음 합니다.

akbar wrote:
그리고 boxing 을 C++ 에서 '어떤 의미'를 찾으려고 하지 마세요. 부질없는 일입니다.

앞서 글을 읽어보시면 알겠지만, "이 boxing을 c++의 것과 비교한다는 것 자체가 좀 다른 개념을 서로 비교한다고느낌이 듭니다. "고 하였습니다만...
제가 "boxing 을 C++ 에서 '어떤 의미'를 찾으려고" 하였나요.. ?? 죄송스럽지만, akbar님께서 제가 하는 말에서 C++과 boxing사이의 연관관계를 찾으려고 하시는 듯 합니다만...

akbar wrote:
C# 이나 java 에서 포인터(참조)가 필요한 곳에 포인터를 넘길때 그 포인터는 스택에 있는 메모리를 가리켜서는 안된다.

라고 하셨는데. 이 문제는 유독 C# 이나 java에서만 국한되는 문제가 아니죠. stack과 heap을 가지고 자료구조를 만들 수 있는 모든 언어/개발환경에 해당되는 얘기인줄로 압니다... 물론 C#이나 java에서 더욱 실수하기 쉬우므로 더욱 조심해야 하는 문제입니다만...
이 문제와 앞서 언급한 문제는 서로 다른 얘기가 아닌가 생각합니다.

CN wrote:
boxing / unboxing이 GC의 frequency가 증가할 가능성이 있다는 의견이 있었습니다.

개인적인 질문입니다만, boxing/unboxing 이 GC의 frequency를 증가시키나요.. ? 저는 그러한 micro optimization에 관한 이슈를 알고 있는것은 아니지만, boxiing/unboxing의 도입이 GC의 frequency를 줄인다고 생각해 왔습니다... 혹시 제가 잘못알고 있었다면, 설명을 좀 해 주실수 있으신지요...

CN wrote:
boxing / unboxing이 부분적으로 어느정도 부하를 만들지 생각하는 것 보다는 전체적인 프로그래밍이 표준에 맞고 논리적으로 맞는지 생각해보고 전체 프로그램을 만든 후에 프로파일링을 통해서 부하를 제거하는 것이 옳다고 믿고 있습니다.

물론 프로파일링을 통해서 각 객체의 디자인의 문제를 수정하는것도 중요하지만, 개인적으로는 그런 프로파일러라는 툴을 이용하는데 중점을 두는 것보다, 디자인적인 측면에서 먼저 문제를 짚고 중점을 두고 넘어가는게 좋다고 생각하고 있습니다...
먼저 객체 디자인시에 객체의 용도등을 고려해서 전반적인 디자인을 하고 프로그램을 구성한 뒤(여기에는 boxing/unboxing의 고려도 포함되어 있다고 생각합니다. 즉 class로 할지 struct로 할지 결정하는것도 중요하다는...), 이후에 (배포하기 전에) 성능향상의 중요한 문제가 있을때 프로파일러를 이용해서 문제점을 짚어나가는게 좋은방법이 아닌가 생각합니다만...
이미 나간 프로그램을 나중에 성능향상을 이유로 class <-> struct 로의 교환도 문제가 있죠.. 그(타입 수정)에따라 이러한 객체를 이미 derived 하여 사용하고 있던 객체들에게 생길지 모르는 문제를 고려해보면, 초기 디자인이 매우 중요하지 않나요? 더군다나 프로파일링이란 것은, 셈플링 대상에만 국한적인 분석법이기 때문에, 모든 문제를 해결하는 방법이 된다고는 생각지 않습니다.
물론 이는 여기 주제와는 좀 동떨어진 얘기지만요.. 좀 다른시각을 보게 되는듯 하네요...

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

죠커의 이미지

htna wrote:
개인적인 질문입니다만, boxing/unboxing 이 GC의 frequency를 증가시키나요.. ? 저는 그러한 micro optimization에 관한 이슈를 알고 있는것은 아니지만, boxiing/unboxing의 도입이 GC의 frequency를 줄인다고 생각해 왔습니다... 혹시 제가 잘못알고 있었다면, 설명을 좀 해 주실수 있으신지요...

MS가 구현한 MSIL의 C#에 한정지어 본다면 다음의 부분이 부분적으로 영향을 미칠 수 있습니다. 순수 struct를 이용해서 value-type으로 사용할 때 아래와 같은 결과를 보입니다.

단점
stack에 저장된 상태를 managed heap에 복제하기 위한 공간과 시간,
object를 완성하기 위한 overhead 공간과 시간,
method table pointer와 sync block index 생성을 위한 공간과 시간
compil-type checks가 run-type checks로 바뀌어 생기는 runtime 시간 증가

장점
배열, 콜렉션, 메소드의 인자, 리턴 타입에 사용할 경우 공간, 시간 절약

하지만 실제 프로그램 실행에서 전체적으로 어떤 영향을 미치는지는 프로파일링만이 답을 줄 것입니다.

대부분의 micro optimization이 실제 프로그램의 수행속도 단축에 큰 영향을 끼치지 못하거나 오히려 부정적인 영향을 미치는 것이 사례를 통해 증명되어 있기 때문입니다. (아예 잘못된 디자인이라면 예외입니다만..)

정재윤의 이미지

CN wrote:

패러다임에 대한 얘기는 저의 실수라는 것을 인정합니다. 구체적인 구현에 의존하지 않는 다는 말에 부정적으로 대답하셨길래 C#과 Java가 Unified type model을 체택하기 때문에 boxing / unboxing이 중요하다는 것에 대해서 반대하는 분이신 줄 알았습니다. 게다가 글의 첫부분의 눈물이 날 지경이라는 부분과 C언어 소스를 보았을때 C언어를 통해서 기술적으로 boxing / unboxing이 필요없다고 말할려는 분이신 줄 알았습니다.

제글의 요지는 uniform한 접근을 위해서 boxing을 쓴다는 설명입니다. 간단한 걸 복잡하게 설명하고 있어서 글을 쓴 것입니다. 지금도 "Unified type model"이라는 거창한 용어가 무엇인지 모르겠군요. 눈물 어쩌구는 java가 boxing/unboxing을 처음 도입했다는 님의 언급도 있고해서 제가 좀 오바를 했습니다. 거친 표현으로 무리를 일으켜 죄송합니다.

CN wrote:

언어의 스펙은 구체적인 구현에 의존 하지 않고 논리적으로 구성할려고 합니다. 이 부분에 대해서는 중복되는 이야기를 하게 되는 군요.

순환고리를 끊기 위해서 권유하자면 ISO C/C++ 표준을 읽어 보십시요.


"구체적 구현"에 의존하지 않도록 스펙을 기술한는 것은 당연합니다. "스펙에서의 근거는 일반적으로 기술적인 부분보다는 논리적인 부분입니다." 이게 위에 님이 쓰신 글입니다. 여기서 님이 사용한 "논리적"이란 단어의 의미가 비합리적인 것에 반한 뜻은 아닐 것으로 생각되는바, rationale을 기술 한다는 의미라고 생각됩니다만 아니였던가요? "명세서"라고 한다면 그런 부분이 아닌 단순한 명세만이 있어야 합니다. C/C++표준에 일반적인 명세들과 다르게 친절하게도 그런 언급이 있다고 하더라도, 이해를 돕기 위함이지 구체적 구현에 의존하지 않기 위한 것은 아닐겁니다. 엄밀하 말하면 구체적인 구현과는 하등의 관계가 없습니다. 제가 말한 "단순한 기술적인 기술"도 역시 구체적 구현과는 전혀 관계가 없구요. 순환고리를 끊기 위해서는 표준 문서 운운보다는 애매한 말을 사용하시는 님의 표현이 수정이 되어야 한다고 봅니다만.

CN wrote:

boxing / unboxing이 부분적으로 어느정도 부하를 만들지 생각하는 것 보다는 전체적인 프로그래밍이 표준에 맞고 논리적으로 맞는지 생각해보고 전체 프로그램을 만든 후에 프로파일링을 통해서 부하를 제거하는 것이 옳다고 믿고 있습니다.

님의 위에 GC에 관한 언급에서 이걸 유추하지 못한 것의 저의 무지인가요? 현학적인 님의 표현의 문제인가요? boxing/unboxing의 부하를 GC가 바로 지우지 못한다는 것에서 찾는 발상 자체가 이미 이상한 겁니다. 제 딴지의 요지는 그게 문제라고 한다면 그걸 해결하는 GC는 얼마든지 있다는 거였습니다.

@주제와는 상관없는 글만을 계속 써서 죄송합니다.

akbar의 이미지

...

죠커의 이미지

정재윤 wrote:
제가 말한 "단순한 기술적인 기술"도 역시 구체적 구현과는 전혀 관계가 없구요.

정재윤님이 말씀한 "단순한 기술적 기술"이 구체적 구현에 의존한 서술을 말씀한 것으로 이해하고 있었습니다. 내가 오독한 것이라면 미안합니다.

정재윤 wrote:
boxing/unboxing의 부하를 GC가 바로 지우지 못한다는 것에서 찾는 발상 자체가 이미 이상한 겁니다.

그 발상을 내가 한 것인가요?

htna의 이미지

akbar wrote:
엉뚱한 해석하지 않게 하실거면 글을 좀 탄탄한 구성으로 써야 할 것입니다.

나름대로 설명을 충분히 붙였다고 생각이 듭니다만. 물론 어떤 설명이든 자신의 생각을 완전히 표현하기에는 부족합니다. 하지만, akbar님께서는 좀 완고하게 해석하시는 듯 하군요. 예제 앞뒤로 설명을 붙였는데. 굳이 잘못해석될 수 있는 부분만 가지고 짚어나가시는 것도 좀 그렇군요.
그 아래에 "프로그램세계에서는 문자 A 를 꼭 A 가 아니고, 어떤 상황에서는 B 이전에 있는 문자라고 설명해도 인식을 해야하는 것입니다." 라고 말을 붙이셨으면서도 말이죠... 이는 유두리있게 이해할 수 있어야 된다는 얘기겠죠?

akbar wrote:
boxing 과 C# java 와의 관계와 그것이 C++ 에서 어떤 (개념이 아닌 실제)동작과 상응하는지에 대한 확실한 감을 못잡고 있는 것입니다.

akbar님께서 제가 감을 잘못잡고 있다고 몰아가고 있다고 느낌이 드는군요. 충분히 이해하고 있습니다. 어떻게 시험이라도 봐야 할까요?

akbar wrote:
그러면 C++ 에서 아주 정상적으로 포인터가 스택 메모리를 가리킬 수 있는 것은 뭡니까.

struct info {
	int* pInt;
	...
}
void func(info* pInfo) {
	*(pInfo->pInt) = 10;
	...
	delete pInfo;
}
int k;
info* pInfo = new pInfo;
pInfo->pInt = &k;
func(pInfo);

이런 코드가 발생할 수 없습니까? 저 코드가 비정상적입니까? 오류가 있나요? 물론 그리 좋은코딩방식은 아니겠지만, 저러한 코드를 비정상적이다 보지 마시기 바랍니다. 경우에 따라 저런 코드가 정상적일 수 밖에 없는 경우도 있습니다. (물론 예가 너무 짧게 되어 있기에 문제점으로보일 수 있겠지만.)

akbar wrote:
C++ 에서 stack 에서의 객체생성을 막고 싶을 때 어떻게 하는지 알아보시기 바랍니다.

굳이 C++에서 stack에 객체 생성을 막고싶지는 않습니다. stack에 객체생성하는게 일을 더 쉽게 해결하는 경우가 많기 때문입니다.
하지만, stack에 객체생성을 막아야 할 때도 있겠죠. 제가 stack에 객체생성되는 것을 막아야 하는데, 의도와 다르게 stack에 객체가 생성되면서 문제가 발생하는 것,이라고는 언급하지 않았습니다.
akbar님처럼 C++에서 stack에 어떠한 객체도 생성이 되는것은 막아야 된다고 생각하지는 않습니다. akbar님도 그렇게 생각하시리라 봅니다만...

akbar wrote:
C#이나 java에서는 포인터가 (혹은 그에 상당하는 어떤 것이) 스택메모리를 가리키는 것을 언어 설계에서 막고 있거나 아니면 다른 안전 장치를 해놓고 있습니다. 따라서 C#이나 java에서 그런 실수(포인터가 스택메모리를 가리키는) 는 좀처럼 안일어납니다. 때문에 C#이나 java에서 더욱 실수 안하므로 '덜 조심' 해도 되는 문제입니다.

프로그램을 작성하는데 있어서 실수를 할 수 있는것에 있어서 덜 조심해도 되는것과 더 조심해야 되는것이 구분이 있는지 궁금합니다만... 그런 덜조심과 더조심을 구분해야 하나요?
안전장치가 있다고 완전히 안전해지는것은 아닙니다. 물론 많은 실수를 커버할 수 있겠지만, 도리어 실수가 생길 수 있다는 사실을 망각하게도 합니다.
제가 C/C++ 책을 보면서 pointer가 stack의 객체를 가리키지 않도록 조심하라는 얘기는 보질 못했습니다만.
C#책을 보면서는 pointer가 stack의 객체를 가리킬 때 문제가 생길 수 있으니 조심하란 얘기를 본 기억이 있습니다만... (제가 잘못 본 것인가요? 음.. 정말 잘못본 것이라면, 제 실수이겠군요. 이번주인가에 MS에서 직원이 와서 강의한다고 하는데. 함 물어보죠. 이런경우가 발생할 수 없는지... 그리고 그러한 것들을 막기위한 얼마나 완벽한 안전장치가 있는지...)
(C++을 너무 오래전에 본 것이라 잊어먹은 건가요. ?)
이렇게 언급할 정도면 도리어 조심해야 하는게 아닌가요?

CN wrote:
MS가 구현한 MSIL의 C#에 한정지어 본다면 다음의 부분이 부분적으로 영향을 미칠 수 있습니다. 순수 struct를 이용해서 value-type으로 사용할 때 아래와 같은 결과를 보입니다.

단점으로 보이는것은 거의 boxing과정중에 발생할 수 있는 overhead 인듯 합니다.
저는 처음에 stack->heap 으로의 메모리 복사만 생각했지만, 그밖에 몇가지 과정이 더 있다는걸 간과한듯 합니다. 하지만, 이들은 boxing과정중에 생길 수 있는 overhead 이지 boxing/unboxing(이라는 개념)이 GC의 frequency에 영향을 주는것은 아니었다고 생각합니다.
물론 잘못된 struct의 선택은 이러한 boxing/unboxing 과정중에 발생하는 overhead에 의해 모든 객체를 class로 했을때 보다 성능이 나빠질 수 있지만, 제가 알기로는 C#에서 class만 사용해서 프로그램을 진행할 경우, struct와 class를 혼용했을 때보다 성능이 더 나쁘다고 알고 있습니다. class로만 객체를 구성했을때에는 더이상 선택의 여지가 없지만, 필요에 따라 struct로 할 경우 프로그래머의 선택에 따라 더 나은 성능을 보일 수 있다는 것은 자명한 일이 아닌가 생각합니다. 그리고 이것은 struct의 boxing/unboxing과정에 생기는 overhead보다 garbage collection에 발생할 수 있는 overhead가 더 클 수 있다는 것을 직/간접적으로 의미하는 것이라 보구요.

micro optimization은 이러한 class/struct boxing/unboxing 과는 직접적인 상관이 없는듯 하네요.
혹시 그에대해 읽을 수 있는 artical 이나 reference를 얻을 수 있을런지요.. 흥미로운 부분이네요.
예전에 학부과정중에 들어본 기억이 어렴풋이 나기는 하지만, 직접 이러한 article을 읽어보는것도 상식을 기르는데 좋은일이 될 수 있을것 같네요..

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

akbar의 이미지

...

weongyo의 이미지

akbar wrote:
java 나 C# 에서 포인터가 스택메모리를 가리키지 않도록 어떤 안전장치를 했는지 생각이라도 해보셨나요.
위 내용은 C#(을 필두로 하는 dotnet) 이나 java 가 C/C++ 과는 다른 기본설계상의 차이를 인식하는 사람의 말이 아닙니다.

말씀을 하실 때, 자세히 이야기 하실 수 없으신가요? 어떤 안전장치를 했다고 하면 어떤 안전장치인지 자세히 이야기해주셨음 합니다. 항상 남이 해답을 찾기를 바라시는 듯 하면서, 먼가 사람들로 하여금 벽을 만드는 듯한 어조입니다. 말씀을 하실 때, 정확한 용어를 같이 사용하시면 그 벽을 못 느끼도록 타인을 배려할 수 있을 듯 하네요.

"어떤 안전장치" 는 상상하기 나름입니다. 그에 대한 개념이 있다면 구현하면 그만입니다. 선택은 컴파일러 개발자나 VM 개발자가 알아서 할 몫입니다. 결국 저희는 사용자이죠.

akbar 님은 C# 혹은 java 컴파일러를 개발해 보셨나요? 혹은 C# 혹은 java VM 을 만들어 보셨는지요? 만들어 보셨다면 위에서 이야기 했던 것이 그냥 하나의 구현 차이라는 것을 느끼셨을 겁니다. 조금의 차이입니다.

항상 java 는 이래야 하고, c# 은 이래야 하고, c/c++ 는 이래야 한다라는 고정 관념은 원래 없습니다. '표준'이라는 것이 있지만, 결국 사람이 하는 거잖아요.

무엇을 이야기하든 '표준' 과 '개념', '개발자의 구현' 만 있으면 어떤 이야기나 상상의 나래를 펼치면 그만입니다.

C++ 도 C 에 만족하지 못했던 어떤 사람의 상상의 나래로 현실화된 개체인 것 뿐이라고 전 생각합니다.

위 내용은 C#(을 필두로 하는 dotnet) 이나 java 와 C/C++ 의 다른 기본설계상의 차이를 말 할려고 한 것이 아니라, 언어 설계 때 어떠한 개념을 언어에 적용하느냐에 따라, 사용자의 사용에 있어서 문제될 수 있는 부분을 지적한 말 같군요.

atie의 이미지

C#에서는...

Quote:
One of the strong features of C# is that it has a unified type system. Every type, including the simple built-in types such as int, derive from System.Object. In C# "everything is an object."
A language such as Smalltalk also has such a feature, but pays the price of inefficiency for simple types. Languages such as C++ and Java treat simple built-in types differently than objects, thus obtaining efficiency but at loss of a unified type system.

C# enjoys the best of both worlds through a process known as boxing. Boxing converts a value type such as int or a struct to an object reference, and is done implicitly. Unboxing converts a boxed value type (stored on the heap) back to an unboxed simple value (stored on the stack). Unboxing is done through a type cast.

int x = 5;
object o = x; // boxing
x = (int) o; // unboxing

Java에서는...

Quote:
Autoboxing, introduced in Java 5, is the automatic conversion the Java compiler makes between the primitive (basic) types and their corresponding object wrapper classes (eg, int and Integer, double and Double, etc). The underlying code that is generated is the same, but autoboxing provides a sugar coating that avoids the tedious and hard-to-read casting typically required by Java Collections, which can not be used with primitive types.

//boxing
int primitiveVal = 1;
foo(Integer.valueOf(1));
//boxing -- new way with Java 5
foo(primitiveVal);

//unboxing
Integer wrapper = new Integer(1);
bar(wrapper.intValue());
//unboxing -- new way with Java 5
bar(wrapper);


아닌가요?
그리고, 한 자바 포럼에 있는 글 중에 인용입니다.
Quote:
Testing on my lowly P3/1Ghz laptop with JDK 1.4.2 (Hotspot server), I see average 70ms per 1 million boxing+unboxing operations. That means I am seeing 15,000 boxing+unboxing operations per millisecond, including GC time (because I run the entire thing in a big loop to force it to include GC times.) Keep in mind that my notebook is a bit slower than the typical modern server ;-)

Java에 관한한(C#도 마찬가지일 거라 생각하면서) boxing과 GC, 그리고 VM의 Garbage Collected heap을 덧붙여 성능에 대해 이야기하는 것은 오바라는 생각입니다. GC'ed Heap에 대한 이야기는 96년에 나오는 내용이고 프로그래머가 그거 알지 말고 프로그래밍 하라고 만들어 놓은 자바이니 말이죠.

----
I paint objects as I think them, not as I see them.
atie's minipage

htna의 이미지

atie wrote:
C#에서는...

좋은글 감사드립니다.
이 코너를 통해서 많은 간과하고 있던것들을 정리하고,
애매하게 생각하던것들을 정리하게 하는 좋은 계기가 되었던듯 합니다.
제가 생각하던것은 이겁니다. C#에서 struct를 재정의한 이유가, 프로그램의 성능을 높일 수 있는 방법을 제공하기 위해서가 아닌가 하는 겁니다. 그렇지않다면 굳이 struct를 이용해 boxing/unboxing 이라는 개념을 이용할 이유가 없지 않았나 하는 것입니다. 물론 그 배경에 uniform이란것이 있다고는 하지만, uniform만을 이유로 든다면 class 만 있어도 되지 않나 생각해서 입니다.
말이 길어지네요..
많이 배우고 갑니다.

PS:
근데 정말 garbage collection을 고려하지 않아도 되나요? 특히 계산량이 많은 프로그램에서는... 저희 회사 프로그램처럼요...

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

akbar의 이미지

....

warpdory의 이미지

쭉 읽어보고 있는데요.

뭔가 좀 얘기가 이상한 쪽으로 흐르는 것 같군요.

gtk+ 가 객체지향적이냐 아니냐... 가 주제 아니었던가요 ?
근데, 객체지향하고 if 남발하고는 별 상관없는 것 같고...(객체지향 프로그래밍이라는 걸 잠깐 손 댄적 있는데, 거기에 if 쓰면 안된다는 구절은 없는 것 같았습니다. 혹시 그런 구절 나온 거 있으면 참고가 되겠네요.) .. 함수 하나가 몇백줄이든 몇 만줄이든 .. 그것도 객체지향하고는 별 상관이 없는 거고(짧을 수록 좋다고는 하지만, 구현하다보면 꼭 그렇게 되는 것만도 아니니...)

------------------------------

지금 보면 서로 생각하는 '객체지향'의 정의도 다른 것 같고..
또 gtk+ 가 객체지향적이냐 아니냐 와는 큰 상관없는(지엽적으로는 관련 있을지는 몰라도) 포장/포장풀기, 쓰레기 수거 .. 이런 것에 초점에 가 있는지.. 애매하군요.

-------------- 이상은 프로그래밍에서 손 땐지 7년된 사람이 지켜보다가 헷갈려서 쓰고 가는 글입니다.


---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.

iolo의 이미지

1년 넘은 쓰레드가 다시 열렸군요 lol
다들 불꽃을 기다리나 봅니다. 이 글이 올라왔다고 저에게 따로 알려주시는 분이 계신걸 보면 ^^;

모르는 새에 생긴 글들과... 제가 쓴 글들을 대충 읽어보느라 시간이 좀 걸렸습니다.

akbar님께 몇가지만 짧게 여쭙겠습니다:

1. GTK는 객체지향적이지 않다고 말씀하시는 건가요? 이것이 이 쓰레드의 주제니까요 -.-;

2. C++에 박싱이 있다는 것입니까? 그렇다면 박스안에 들어갈 내용물은 무엇이고, 박싱한 결과는 무엇입니까? 왜 그렇게 해야합니까?

그리고, 이 부분은 갑자기 왜 인용된건지 잘 이해가 안갑니다만:

akbar wrote:

iolo wrote:

iolo 씀:
여기에서 제가 주장하고 싶었는 것은
'나름대로의 원칙을 갖고 만들어진것은, 그 원칙을 모르면 복잡해 보이지만, 그 원칙을 알고나면 쉬워진다'입니다.
리스프를 모르는 사람에겐 리스프의 끝없는 괄호 조차도 어지러워 보이겠죠.

그렇다고 그 원칙을 강요해서는 안됩니다.
리스프에서 지리한 괄호가 1000 개가 있는 곳을 500 개로 짤 여지가 있다는 것을 생각하지 않은채
'지리한 괄호가 1000 개가 있더라도 어지럽지 않게 보일때까지 원칙을 공부해라' 는 것과 같은 억압은 사양합니다.

그래서, 리스프로 만들어서 지리한 괄호로 가득한 에막스의 코드는 스파게티입니까? 생소한 기호로 가득한 현대 물리학의 공식들은 스파게티입니까? 아니죠. 내가 모르는 것일 뿐...
전 1000개의 괄호가(GTK의 소스코드가) 쉽게 보일때까지 원칙을 공부하라고 강요하지 않았습니다. 다만, 1000개의 괄호에는 그 나름의 의미가 있다는 것입니다. 그 의미를 무시하고 스파게의 의미를 왜곡하지는 말자는 거죠. 1000개의 의미도 모르고, 그걸 500개로 짤 수 있습니까?

1년의 세월이 지나는동안 akbar님의 내공이 많이 올라가셨네요.
앞의 글들에서 자신이 쓴 오류들을 인정하시는 자세가 필요하지 않을까요?

----
the smile has left your eyes...

죠커의 이미지

akbar wrote:
CN wrote:
boxing이 C/C++에서 의미없다는 말은 foundation classes를 사용하는 언어들에서 &과 *가 의미가 없다고 말하는 것과 비슷하게 들립니다. 눈 두개 가진 사람은 눈 하나 가진 사람들의 마을에서는 이상한 사람입니다.

누누이 강조했듯이 C++ 에서 boxing 는 별의미가 없습니다.
& 과 * 이 차지하는 의미와 엇비슷한 비중을 가지는, '어떤의미' 의 boxing 을 C++ 에서 찾는 것은 뜬구름과 같은 것입니다.
boxing 이 C 에서는 그렇게 중요한것인가요.

같은 이야기인 것 같습니다. 관점이 틀리기 때문에 의미가 없다는 것입니다. C나 C++의 Unified type 개념을 채택하지 않는 이상 영원히 불필요할 지도 모릅니다. :-)

htna wrote:
atie wrote:
C#에서는...

좋은글 감사드립니다.
이 코너를 통해서 많은 간과하고 있던것들을 정리하고,
애매하게 생각하던것들을 정리하게 하는 좋은 계기가 되었던듯 합니다.
제가 생각하던것은 이겁니다. C#에서 struct를 재정의한 이유가, 프로그램의 성능을 높일 수 있는 방법을 제공하기 위해서가 아닌가 하는 겁니다. 그렇지않다면 굳이 struct를 이용해 boxing/unboxing 이라는 개념을 이용할 이유가 없지 않았나 하는 것입니다. 물론 그 배경에 uniform이란것이 있다고는 하지만, uniform만을 이유로 든다면 class 만 있어도 되지 않나 생각해서 입니다.
말이 길어지네요..
많이 배우고 갑니다.

PS:
근데 정말 garbage collection을 고려하지 않아도 되나요? 특히 계산량이 많은 프로그램에서는... 저희 회사 프로그램처럼요...

struct를 value type으로 한 것은 분명히 속도를 고려해서 만든 것입니다. reference type만을 고려한다면 boxing / unboxing등의 거추장스러운(?) 개념이 없더라도 매끈하게 돌아가니깐요.

boxing / unboxing이 도입되어 있다는 것은 boxing을 쓰더라도 순수 reference type만을 쓰는 것보다 효율적이고 value type을 직접쓰는 것보다는 편리한 점이 있기 때문일 것입니다. 그렇기 때문에 boxing / unboxing을 고의적으로 오용하지 않는다면 특별한 문제는 없다고 생각합니다.

이전 부터 말씀드렸지만 현대의 컴퓨터 상에서 지엽적인 optimization으로 프로그램의 성능을 알기는 어려운 것입니다. 인간이 최적화한 코드가 C/C++ 컴파일러가 최적화 해준 코드보다 훨씬 느린 사례들이 종종 발견됩니다. Software Engineering의 대가들이 종종 프로그램이 논리적으로 맞다면 최적화는 최대한 미루고 프로파일링에게 맞겨라고 말하는 것은 근거가 있습니다.

akbar의 이미지

...

iolo의 이미지

먼저... "C++에는 없는 박싱을 GTK에선 C로 구현했다" 고 한 부분은 분명히 저의 경솔한 판단이 었습니다. "(C++이라면 더 쉽게 구현할 수도 있는 박싱을) C로 힘들게 구현했다" 정도면 될까요?
그리고 자바 1.5에 새로 추가됐다고 한 "박싱"은 "오토박싱"을 의도한 것이었습니다. 뭐 이건 분명히 C++에서는 불가능한 얘깁니다만...(새로운 불씨인가요?)
제가 초반에 용어를 잘못써서, 쓰레드 전체에 걸쳐서 박싱과 오토박싱에 대해서 혼동이 있군요.

akbar wrote:

지존께서 총애하시던 오웬타일러나 데이빗커틀러 는 모두 안녕하시온지요.
스트라우스트럽 선생님은 잘 계시옵니다.

제가 뭐라고 저런 사람들을 총애하겠습니까. 총애받지도 못하는 처진데...
까마득한 사람들이지요. 제가 유명한 사람 몇 언급했다고... 혹은 짠빱 과시했다고 너무 비아냥 거리지마세요. 그냥 언급한것일뿐인데... 이렇게 까지...

akbar wrote:

iolo wrote:

iolo 씀:
1. GTK는 객체지향적이지 않다고 말씀하시는 건가요? 이것이 이 쓰레드의 주제니까요 -.-;

아니옵니다.

아... 이런... 한 줄로 답변해주셨는데... 객체지향이라는 건지, 아니라는 건지 모르겠습니다.(제가 질문을 이상하게 해놔서...-.-)

객체지향이 아니라고 하신다면 이 토론은 계속 될것이구요...

객체지향이라고 하면... 마지막 반론자가 없어졌으니... 더이상의 토론은 무의미하겠죠.

akbar wrote:

C 에서는 박싱이 있다는 것이옵나이까. 도데체 무엇을 담고 있나이까 또 결과는 무엇이며 왜 그렇게 해야하나이까.
이 천민을 불쌍히 여기시어 가르침을 주시옵소서

그건 이 쓰레드가 길어진 원인이 된 글에서 제가 밝힌 바와 같은데... 이렇게 되물으시니 당황스럽습니다.
저도 한줄로 대답하죠. 없습니다.
쓰레드가 너무 길어지고 가지가 많이 뻗어서... 정리가 안돼서 정리를 하자는 의미로 다시 여쭌 것인데... 뭔가 의도한 결과는 아니군요-.-;
그래서 쓰레드를 다시 읽어봤는데.. 여전히 모르겠습니다. akbar님이 말씀하시는 박싱은 자주 바뀌어서요... 타입캐스팅? 타입캐스팅연산자오버로딩? 가베지콜렉션..어쩌구한거? 스택/힙..어쩌구한거? 어떤것인가요? 이 쓰레드를 보시는 분(저를 포함해서)들을 위해서 번거로우시더라도 정리해주시면 좋을 듯합니다. 그게 다소간의 불미쓰런 글들이 있었던 쓰레드를 의미있게 만드는 일 아니겠습니가?

박싱에 대한 얘기는 "GTK가 객체지향인가"라는 물음의 차원을 넘어선것 같으니, 따로 쓰레드를 여시는 것이 좋을 듯 합니다.

그리고, "스파게티"에 대한 얘기는 이 쓰레드와는 좀 거리가 있는 것 같으니...
더 얘기하실려면 따로 쓰레드를 여는게 좋을 듯 합니다. 이건 뭐랄까... 약간 철학적인 부분이라고 해야하나요? 충분히 서로 다른 의견을 가질 수 있는 부분이라고 생각이되네요...

----
the smile has left your eyes...

akbar의 이미지

...

akbar의 이미지

...

iolo의 이미지

자기가 쓴 글이라고 해도... 퍼블리싱 된 이상...
임의대로 수정하는 '만행'은 그만두시길 바랍니다.
수정을 하더라도... 원래 쓴 글은 남겨두어야 할 것이고...
그 글이 문제가 있었다면... 이러이러한 이유로 수정한다고 밝히는 것이 도리아니겠습니까?

수정되기전의 원래 글에 달린 댓글들을 바보로 만드실 생각입니까?

이런식의 행태가 계속되는 akbar님의 글에 댓글을 다는 것은 '자살골'과 다를 바가 없다는 생각이 드는군요.

----
the smile has left your eyes...

akbar의 이미지

...

warpdory의 이미지

토론을 하자는 것인지, 개인에 대한 험담을 하시자는 것인지, 악담을 하시자는 것인지요 ? 제가 보기엔 개인에 대한 저주에 불과한 글이군요.

이런 글까지 kldp 에, 그것도 토론, 토의 게시판에 올라와야 하는지 의문스럽습니다.

C++/Java/C/박싱/언박싱 .. 이런 것보다는 역시 중요한 것은 따로 있는가 봅니다.

akbar wrote:
iolo wrote:
자기가 쓴 글이라고 해도... 퍼블리싱 된 이상...
임의대로 수정하는 '만행'은 그만두시길 바랍니다.

아마 새글을 올리면서 이전 글 하나를 삭제한 것을 얘기하시나본데
그 글은 'kldp 가 중독성이 있어 가끔은 미울때가 있다' 라는 것이었습니다.
또한 iolo 님이 답변을 기다리실까바 며칠 걸릴 것 같다는 내용도 담았습니다.
새글을 올릴 때 이 글이 흐름을 방해하지 않을까 싶어 지웠던 것입니다.
그런데 만행 이라구요
그런 까앙ㅍㅐ나 쓰는 말을 제가 들어야 합니까.
iolo 님의 답변을 준비하느라 3 시간이나 정성들여 준비한 사람한테 이게 할 소리입니까.
누구는 시간이 남아 도는 줄 아시나요.

이런 일이 생긴게 오히려 다행입니다. iolo 님의 실체를 알았으니까요.

iolo wrote:
먼저... "C++에는 없는 박싱을 GTK에선 C로 구현했다" 고 한 부분은
분명히 저의 경솔한 판단이 었습니다. "

iolo 님이 자신의 경솔함을 인정하는데 자그마치 1 년이 걸렸습니다. 1 년 이나요.
이쯤에서 iolo 님이 C++ 에 대해서는 신중한 접근을 하실 줄 알았습니다. 그런데

iolo wrote:
그리고 자바 1.5에 새로 추가됐다고 한 "박싱"은
"오토박싱"을 의도한 것이었습니다.
뭐 이건 분명히 C++에서는 불가능한 얘깁니다만...(새로운 불씨인가요?)

갑자기 이런 망언을 되풀이 하는 것은 이 무슨 행패 입니까.
iolo 님의 경솔함을 증명하는데 또 시간을 허비해야 하나요.
iolo 님의 경솔함을 고치는데, 지난번에는 1 년이 걸렸으니까,
이번에는 그 이상의 기나긴 시간을 잡아먹을 것 같네요.
iolo 님이 21 년 경력의 자바의 대가라고 해서
특별한 C++ 공부없이도 C++ 의 대가 인척 한다면
그게 과연 누구에게나 통할거라고 생각하십니까.

akbar wrote:
iolo wrote:

GTK는 널리 쓰이는 좋은 라이브러리입니다.
그걸 스파게티든 라면이든 비판하고 싶으면
대단한 자신감과 이를 뒷받침하는 실력, 그리고 체계적인 접근이 필요한 겁니다.
akbar님도 상당한 경력을 가진 분으로 보입니다만,
스스로를 오웬타일러 정도라고 생각하십니까?
저도 20년을 이짓으로 용돈벌고 학비대고 밥먹고 살고 있지만
오웬을 보고 있으면 까마득하고 어지럽네요...

"C++ 의 객체구현이나 gtk 의 객체구현이나 대충 비슷비슷하지 뭐가 차이가 있냐"
는 어투가 굉장히 귀에 거슬립니다.
C++ 에 대해 정말 아는 체 하시려거든 대단한 자신감과
이를 뒷받침하는 실력, 그리고 체계적인 접근이 필요한 겁니다.
iolo 님이 20 년 경력이라고 해서 스스로를
스트라우스트럽 정도나 된다고 생각하십니까.
20 년 중에 "다소 제한적인 객체지향의 자바"를 뛰어 넘어
객체세계를 바라본 것은 도데체 몇 년이나 됩니까.

바안~~~~복 합니다.

-- gtk C 는 객체지향적이긴 하지만 플머에 따라 어지럽게 보일 수 있다. --

는 것입니다.
여기에 또다시 태클을 거실거면 제발 C++ 얘기는 하지 말아 주십쇼
대응할 가치가 없는 경우가 종종 있어서 20 년이라는 경력만 의심스럽게 만듭니다.

이런 내용을 듣고도 C++ 에 대해서 태클을 걸고 싶으세요
대응할 가치가 있어 주기를 바라십니까.

iolo 님이 boxing 대한 정리를 부탁한다고 하셔서
어저께 특별히 시간내어 장장 3 시간 동안 눈 비비고 머리아픈것을 참아가면서
정리를 해서 글을 올렸었고 동시에 gtk c 의 객체설계가
어떻게 이루고 지고 있는 것인지 간단한 해설을 해주십사 청했었읍니다.
iolo 님이 답변을 주셨길래 gtk c 내용일거라고 생각하면서 얼른 클릭해서 열어봤더니
이건 까앙ㅍㅐ 나 쓰는 표현으로 도배를 해놓으셨더군요.
제가 iolo 님한체 이런 무식한 대접을 받아야 되겠습니까.
3 시간 동안 고생한 제가 이렇게 한순간에 등신이 되어야 합니까.
iolo 님은 남들이 몇 시간 작업한 것을 보여주면
이전에 기억하고 있던 내용이 일부 없어졌다는 이유로
까앙ㅍㅐ 처럼 다룹니까.
혹시 gtk c 의 객체설계를 해설할 자신이 없었나요.
그러면 그렇다고 말씀을 할 것이지 왜 사람을 기다리게 만듭니까.
나름대로 심혈을 기울였던 어제의 그 시간과 함께
그동안 iolo 님을 상대했던 그 시간까지도 너무 억울합니다.

iolo 님은 다른 사람의 노고를 생각하는 사람이 아닙니다.
iolo 님은 혹 권력실세인가요. 아니길 바랍니다.
아랫사람들 실컷 부려먹고 작은 꼬투리를 잡아서 언젠가는 버릴 준비를 하는 분이니까.
혹시 팀장정도 되나요.
21 년 정도 경력이면 그래야 겠지요. 그러면 팀원들이 잘 따릅니까.
iolo 님이 맡은 프로젝트가 모두 무사히 끝났었습니까.
혹시 팀원들 중에 너 나중에 도구보자 는 심정으로
떠나게 됐던 팀원들은 없는지 돌아보시기 바랍니다.

세파에 부딛히게 되면 iolo 님과 같은 마인드를 가질까봐 무척 두렵습니다.
꼭 피해야 하겠지만 과연 쉽게 피해질지...

주위에서 iolo 님 같은 분을 자주 보게 됩니다.
다른 사람의 노고를 생각하는 것을 체질적으로 싫어하는 그런 사람 말입니다.
만약 그 사람이 생각해주는 척 한다면 그것은 등쳐먹기 위한 준비 공작인 것입니다.

이 시점에서 바라는 게 있다면 iolo 님은 높은 분 이 되지 않기를 바랍니다.
아랫사람이 위험합니다.
그러고 보면 나라에서 높은 분이나 iolo 님이나 저지르는 횡포
공통의 기반 클래스에서 상속하고 있습니다.
이승만 부터 시작해서 노무현까지, 변변치 못한 짓이란...
한벌 더 나가 생각하자면 이 높은 분들 때문에
독도가 정말 일본땅이 될지도 모르겠습니다.
위기에 임해서 제 살길을 기가 막히게 찾는 것은 (주로 도망이지만)
선조나 인조나 이승만 혹은 장면의 예에서 알 수 있듯이
우리나라 높은 분들의 전통이지 않습니까.

ps : 이 높은 분들로 인해 고향땅이 오랑캐에게 다시 짓밟혀도 고향을 언제까지나 사랑할 것입니다.


---------
귓가에 햇살을 받으며 석양까지 행복한 여행을...
웃으며 떠나갔던 것처럼 미소를 띠고 돌아와 마침내 평안하기를...
- 엘프의 인사, 드래곤 라자, 이영도

즐겁게 놀아보자.

익명 사용자의 이미지

akbar님은 iolo님의 짧은 지적에 대한 적절한 답이 나와야 할 곳에 쓸데없는 소리를 하였습니다.

ffnhj의 이미지

akbar wrote:

이 시점에서 바라는 게 있다면 iolo 님은 높은 분 이 되지 않기를 바랍니다.
아랫사람이 위험합니다.
그러고 보면 나라에서 높은 분이나 iolo 님이나 저지르는 횡포
공통의 기반 클래스에서 상속하고 있습니다.
이승만 부터 시작해서 노무현까지, 변변치 못한 짓이란...
한벌 더 나가 생각하자면 이 높은 분들 때문에
독도가 정말 일본땅이 될지도 모르겠습니다.
위기에 임해서 제 살길을 기가 막히게 찾는 것은 (주로 도망이지만)
선조나 인조나 이승만 혹은 장면의 예에서 알 수 있듯이
우리나라 높은 분들의 전통이지 않습니까.

ps : 이 높은 분들로 인해 고향땅이 오랑캐에게 다시 짓밟혀도 고향을 언제까지나 사랑할 것입니다.

언제나 그렇듯 개념없는 논쟁의 말로는 이렇습니다.
gtk C의 코드 스타일에 대한 분석에서 고향땅에 대한 애국심으로의 승화, 정반합의 개념적 발전의 총아를 보는 것 같네요.

익명 사용자의 이미지

왜 굳이 C++놔두고 C로 객체지향을 구현하려 할까요?
C++확실히 괜찮은 언어입니다.
저는 C가 너무 좋아서, C로 객체지향을 구현한다는둥 하는
여러 문서를 기웃거려 보기도 하고,
objectC 등을 구경해보기도 했습니다.
그러나, 익숙해질수록 C++이 확실히 좋은거 같습니다.
어찌 생각하시는지..ㅋ...

hey의 이미지

ㅋ wrote:
왜 굳이 C++놔두고 C로 객체지향을 구현하려 할까요?
C++확실히 괜찮은 언어입니다.
저는 C가 너무 좋아서, C로 객체지향을 구현한다는둥 하는
여러 문서를 기웃거려 보기도 하고,
objectC 등을 구경해보기도 했습니다.
그러나, 익숙해질수록 C++이 확실히 좋은거 같습니다.
어찌 생각하시는지..ㅋ...

gtk를 C로 짰기 때문에 오히려 C++, Java, Python, Perl(공식 지원 바인딩)같이 자기가 맘에 드는 언어로 gtk를 사용할 수 있게 되었고 Ada, CL, Smalltalk, 심지어 자바스크립트까지도 발빠르게 바인딩할 수 있게 되었죠.

C++이 좋으시면 C++ 바인딩을 쓰시면 되잖아요.


----------------------------
May the F/OSS be with you..


akbar의 이미지

영희 wrote:
akbar님은 iolo님의 짧은 지적에 대한 적절한 답이 나와야 할 곳에 쓸데없는 소리를 하였습니다.

지적감사합니다. 부끄러움에 제 글 모두 지웁니다.
cbycby의 이미지

hey wrote:
ㅋ wrote:
왜 굳이 C++놔두고 C로 객체지향을 구현하려 할까요?
C++확실히 괜찮은 언어입니다.
저는 C가 너무 좋아서, C로 객체지향을 구현한다는둥 하는
여러 문서를 기웃거려 보기도 하고,
objectC 등을 구경해보기도 했습니다.
그러나, 익숙해질수록 C++이 확실히 좋은거 같습니다.
어찌 생각하시는지..ㅋ...

gtk를 C로 짰기 때문에 오히려 C++, Java, Python, Perl(공식 지원 바인딩)같이 자기가 맘에 드는 언어로 gtk를 사용할 수 있게 되었고 Ada, CL, Smalltalk, 심지어 자바스크립트까지도 발빠르게 바인딩할 수 있게 되었죠.

C++이 좋으시면 C++ 바인딩을 쓰시면 되잖아요.

질문도 좋고 답변도 거의 좋을뻔 했는데.
마지막은 대체 뭔가요?

또 비아냥 대는 건가요?
내가 올린 질문아니지만, 이런식의 답변은 너무 하는거 아닌가 싶어서 이렇게 남깁니다.

C++이 좋으면 C++ 쓰면 되지 왠 시비냐는 어투군요...

http://www.korone.net QT 커뮤니티 사이트

카二리의 이미지

그 글에 대해서 답글을 단 사람들을 바보로 만드는 무식한 처사입니다.
정말 akbar님에게 실망을 금치 못하게 하는 군요.

어떻게 이렇게까지 포악한 일을 저지를수 있으신지....
정말 실망입니다.

새 생각 :)

hey의 이미지

cbycby wrote:
hey wrote:
ㅋ wrote:
왜 굳이 C++놔두고 C로 객체지향을 구현하려 할까요?
C++확실히 괜찮은 언어입니다.
저는 C가 너무 좋아서, C로 객체지향을 구현한다는둥 하는
여러 문서를 기웃거려 보기도 하고,
objectC 등을 구경해보기도 했습니다.
그러나, 익숙해질수록 C++이 확실히 좋은거 같습니다.
어찌 생각하시는지..ㅋ...

gtk를 C로 짰기 때문에 오히려 C++, Java, Python, Perl(공식 지원 바인딩)같이 자기가 맘에 드는 언어로 gtk를 사용할 수 있게 되었고 Ada, CL, Smalltalk, 심지어 자바스크립트까지도 발빠르게 바인딩할 수 있게 되었죠.

C++이 좋으시면 C++ 바인딩을 쓰시면 되잖아요.

질문도 좋고 답변도 거의 좋을뻔 했는데.
마지막은 대체 뭔가요?

또 비아냥 대는 건가요?
내가 올린 질문아니지만, 이런식의 답변은 너무 하는거 아닌가 싶어서 이렇게 남깁니다.

C++이 좋으면 C++ 쓰면 되지 왠 시비냐는 어투군요...

음. 죄송합니다.
C++이 좋으시면 C++ 바인딩을 쓰시면 되리라고 봅니다 <- 이정도 어때요?


----------------------------
May the F/OSS be with you..


익명 사용자의 이미지

[Off Topic]
토론이 옆길로 새지 않으려면 상대방의 글 쓰는 태도에 관해서는 일절 언급하지 않는편이 좋다고 봅니다. 특히 의도하지 않았을 수도 있는 표현상의 실수까지 일일이 지적하는 순간부터 쓰레드는 더이상 토론이 아니라 싸움입니다.

죠커의 이미지

ㅋ wrote:
왜 굳이 C++놔두고 C로 객체지향을 구현하려 할까요?
C++확실히 괜찮은 언어입니다.
저는 C가 너무 좋아서, C로 객체지향을 구현한다는둥 하는
여러 문서를 기웃거려 보기도 하고,
objectC 등을 구경해보기도 했습니다.
그러나, 익숙해질수록 C++이 확실히 좋은거 같습니다.
어찌 생각하시는지..ㅋ...

Objective C로 객체지향을 이용하면 C++으로 객체지향을 이용할때 사용되는 트릭을 이용할 필요가 없습니다. 또 C++과 C보다는 Objective C와 C가 더 연관성이 있습니다. Objective C에서의 C는 완전한 subset이니깐요. 그런데 왜 Objective C를 두고 C++으로 객체지향하십니까?

iolo의 이미지

akbar wrote:

iolo 님이 boxing 대한 정리를 부탁한다고 하셔서
어저께 특별히 시간내어 장장 3 시간 동안 눈 비비고 머리아픈것을 참아가면서
정리를 해서 글을 올렸었고 동시에 gtk c 의 객체설계가
어떻게 이루고 지고 있는 것인지 간단한 해설을 해주십사 청했었읍니다.

뭐 어짜피 망가질만큼 망가진거니까...
쪽팔림을 무릎쓰고 여쭙겠습니다.

힘들게 정리하셨다는 그 글을 어떻게 볼 수 없겠습니까?

문맥을 보면 제가 올린 글 위에 있었다는 건데...
전 그런 글을 본 기억이 없어서요...

그 글을 봤다면 설마하니 제가 저렇게 툴툴거리면서 불평을 올렸겠습니까.

----
꼬리말 어케 쓰나... 에라 모르겠다~ 수동 꼬리말~
"불꽃 속에 살아보세~ lol"

----
the smile has left your eyes...

cppig1995의 이미지

JavaScript가 OOPL 이라는 것에 대한 논증

- 대부분의 Chromeless Window 소스.

Object = new Chromeless();

잘 보면 : 이런 생성자 녀석과 메소드들이...

Chromeless = function()
{
...
}

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

solarisx의 이미지

최초의 C++ 컴파일러는 C++ 소스를 읽어 C코드를 출력하는 프리프로세서였다는 것을...

> cat run.sh
#!/bin/sh
sh ./run.sh
> sh ./run.sh

죠커의 이미지

solarisx wrote:
최초의 C++ 컴파일러는 C++ 소스를 읽어 C코드를 출력하는 프리프로세서였다는 것을...

주제는 다르지만.. 최초의 C언어 컴파일러는 C언어로 짜여졌다는게 기억나는군요.

아마도 최초의 C언어 컴파일러는 C언어 인터프리터에서 작동하지 않았을까 합니다. C언어 인터프리터는 BCPL에서 짜여진게 아닐까란 생각도 드네요 :-)

zetoia의 이미지

열심히 봤는데 2년이나 지난글이군요
그런데 결론이 무엇이던가요?

gtk는 스파게티라는건가요?
gtk는 객체지향이 아니라는건가요?

Darkcircle의 이미지

박싱이고 뭐고 제일 중요한건 스레드 제목의 답변이 있느냐없느냐죠.
이래저래 중간에 참 별 상관도 없는 얘기가 막 튀어나오곤 했는데
박싱의 개념이란게 물론 OOP하고 연관은 있는거겠죠?
하지만... 글 주제하곤 전혀 상관 없습니다. 왜냐구요??
"GTK가 객체지향적이냐?" 는 답변하고는 전혀 상관 없거든요...

근데 iolo님께서 벌써 중간중간에 답변을 내어 주셨네요.
근데 왜 결론을 발견하시지들 못하는건지??
답변들 중에 관련된 내용을 뽑아서 한줄로 정리해보니까 이런 결론이 나오드라구요...

> 눈에 보이는 것이 무조건 순차지향이고 객체지향인 것은 아니다...

그렇죠~ C++로 백날 짠다 한들 객체지향 특성 못살리면 무슨 소용이 _-_);
차라리 저같으면 무식하게 C로 짜버리겠습니다.
( 어차피 제대로 할줄 아는게 C (밖에 없으... 쿠덩~!!) 니까요 :) )
C로 객체지향 스타일로 짜놓고 은폐시킨담에 메인에서 객체지향으로 짜버리면
디버거로 고의적으로 추적하지 않은 이상 그냥 겉에서 돌아가는걸로 봐서는 아마 거의 비슷할 겁니다.

언어 만진지 3년이 흘러가고 부대에서 만진거래봐야 비베 밖에 없다보니
머릿속에 들은건 거의 하나도 없는 일자무식입니다. _-_);;
별로 아는건 없지만 제가 딱 한마디로 정리할께요~\
(이제 글 잠궈도 될거 같습니다. 한표~)

"눈에 보이는 것만으로 결론 짓는건 바보짓이다..."

-------------------------------------------------
니네 군대에서 멀쩡한 몸으로 18시간 자봤어? ㅋㅋㅋ

---------------------------------------------------------------
폐인이 되자 (/ㅂ/)

knight2000의 이미지

Quote:

하나도 안 객체 지향 적이더군요..

소스를 보니 함수 하나가 수백줄이나 되고 완전히 if 문의 남발로 되어가지고 못 알아 보겠는 왜 이걸 객체 지향 적이라고 하죠...

gtk는 그것의 소스 자체보다는 그것이 다른 데에 쓰이는 소스가 객체지향적이라고 하지 않나요?

===== ===== ===== ===== =====
knight2000 of SALM.
SALM stood for SALM Ain't a Life Model.
SALM is not the life model, but SALM is just the life.

Scarecrow의 이미지

class MainWindow : public QMainWindow
{
    Q_OBJECT
    ...
};

http://doc.trolltech.com/4.2/mainwindows-application.html

class HelloWorld : public Gtk::Window
{
    ...
};

http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/ch03s06.html

int main(int argc, char *argv[] )
{
    GtkWidget *window;
    gtk_init (&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    ...
}

http://www.gtk.org/tutorial/c39.html#SEC-HELLOWORLD

위에서 간략히 보인 것처럼 C에서 gtk로 프로그래밍하는 경우는
QT나 gtkmm을 사용할때 상속등을 활용하는 것에 비해
상속으로 새로운 객체를 만들지 않고 그냥 gtk_window를 사용해버립니다.
이는 C에서 상속을 하고, upcasting을 하고, 다형성을 활용하고, 하기가 불편하기 때문이겠지요.
그렇게 생각하면 라이브러리를 적용하는 부분에서도 그리 객체지향적이라고 하기에는 부족할 듯 합니다.

객체지향개념에 기초하여 함수의 인터페이스가 잘 디자인(정리)되어진 라이브러리를
구조적으로 사용하는거라 해야 하지 않을지요.

비행소년의 이미지

오래된 쓰레드 발굴단이 활동하는 모양이군요.

다음엔 어떤 추억의 쓰레드가 발굴될지 심히 궁금 합니다. :)

높이 날다 떨어지면.
아푸다 ㅡ,.ㅡ

onion의 이미지

발굴.. 좋은거군요.. 모처럼 재미있게 읽었습니다...
(대부분은 저에게 알 수 없는 내용이었지만..-.-)

gtk의 smalltalk바인딩은 squeak과 gst의 두가지가 있는데...
gst는.. 참.. 가슴아픈수준이라..(차라리 php-gtk가 더 최근 릴리즈일듯..-.-)
squeak은 꾸준한 프로젝트라서... 나름 쓸모있지 않겠나 싶네요..
후우.. 플밍.. 언제나 다시한번 해볼까요...T.T

-----새벽녘의 흡혈양파-----

-----새벽녘의 흡혈양파-----

iolo의 이미지

ㅎㅎ 묵은 쓰레드 귀신이라도 떠 다니는 모양이죠~

아무튼 기왕 살아난거니.. 저도 댓글 하나~

지나고 나서 읽어보니... 제가 오바한 부분이 있군요.
쓰레드의 시작은 "GTK의 코드"가(libgtk*)가 스파게티라는 거였는데...
제가 단 댓글들은 "GTK로 만든 코드"는 객체지향이다였군요. ^^;

아무튼, GTK를 이용하여 OOD를 적용한 좋은 예가 있어서 소개합니다:

http://tinymail.org/technical.html

maemo라는 노키아의 스마트폰용 플랫폼(qt의 qtopia생각하시면 되겠습니다)을 타겟으로 만들어진,
작고 가벼운(것을 추구하는) imap 클라이언트입니다만... 결과물 보다는 개발 과정이 볼만합니다.
디자인 패턴을 (일부러) 많이 활용한 인터페이스 드리븐 디자인을 C와 GTK로 어떻게 만드는 가를 보여주는 멋진 예제죠.

----
the smile has left your eyes...

----
the smile has left your eyes...

joone의 이미지

http://gnome.or.kr/docs/develop/architecture/ 이 글에서 여기 논쟁이 언급되어 있어서 링크를 추가해봅니다.

페이지