구조체 정렬에 관한
clet 에서 사용하기 위한 C 객체지향 프레임웍을 구현하고 있습니다.
glib 및 ooc 등을 살펴보았고..
결론적으로 위피에서는 제약들이 꽤 있어서 참고로 하되 여러가지 상황을 고려하며 자체적으로 만들고 있습니다.
여기서 확인할려고 하는것은,
구조체 두개가 있다고 할때 두번째 구조체의 멤버는 첫번째 구조체 그것을 포함하고 추가로 다른것이 있다고 할때,
구조체를 멤버로 하지 않고 각각의 멤버를 포함시켰을때도 절대로 각 멤버들의 옵셋은 변하지 않는가? 하는것입니다.
즉,
일반적으론 이렇게 객체 상속을 구현하죠.
struct C1
{
int a;
char b;
};
struct C2
{
struct C1;
int c;
short d;
};
구조체를 통째로 포함시켰을때는 당연히 C2 객체 포인터를 C1으로 캐스팅했을때 각 멤버에 대한 옵셋이 정확히 들어맞겠죠.
헌데 만약, 다음과 같이 C2를 정의했을때
struct C2
{
int a;
char b;
int c;
short d;
};
이때 C1으로 캐스팅한 C2 객체 포인터가 있다고 할때 이때의 C1 멤버들에 대한 옵셋은 절대적으로 동일하게 보장되는가 하는것입니다.
일반적으론 구조체 멤버란것은 메모리상에 연속적으로 배치된 - 물론 패딩을 포함해서 - 변수이므로 두번째 경우도 절대적으로 동일하다고 생각합니다. 테스트에서도 그러하구요.
헌데, 혹시 최적화 옵션이나 ARM CPU의 특성 혹은 확장된 구조체의 추가된 멤버에 영향을 받아서라던지.. 어떠한 경우라도 옵셋이 C1과 다른 경우도 있을 수 있는지요? 그래서 구조체 자체를 필히 멤버로 해야 한다는 그런 당위성이 혹 있는가 궁금합니다.
?
clet이 뭐죠?
그리고 왜 꼭 이 방법을 쓰셔야하는지...
프로그램상에서 종속관계가 아닌 두개의 스트럭쳐를 서로 상호 캐스팅이 가능하게 쓰신다는거 자체가 좀 위험한 발상이시네요.
말씀하셨듯이 최적화 옵션이나 플랫폼, 콤파일러 등등의 변수에 의해 충분히 원하지 않는 결과가 나올수 있을거라고 봅니다.
우선 메모리에서 각 멤버들의 순서가 보장 안되지 않나요?
경험적으로는..
경험적으로는 보장된다고 보는데요...
보장은 못합니다.
위험하긴 하죠. 1%라도..
위험을떠나서라도
위험을떠나서라도 좋지 않은 방법인것 같군요..
프로젝트가 작다면 궂이 저렇게 하지 않아도 될것이며 크다면 저렇게 해서는 안될것으로 생각됩니다만..
----------------------------------------------------------------------------
C Library Development Project
----------------------------------------------------------------------------
원하시는게 OOP적인
원하시는게 OOP적인 특징중 상속이라면, 처음부터 C가아닌 C++로 해보시죠?
=================================
나비아빠
=================================
나비아빠
구조체 선언시
구조체 선언시 나열한 멤버들의 순서대로 구조체 멤버가 메모리에 배치된다는것이 표준에 의해 보장되지 않나요? 만약 이게 안된다면 특정 포맷에 대한 헤더를 구조체로 선언하고, 메모리로 읽어들인 데이터를 해당 구조체로 캐스팅해서 접근하는 방법 자체가 portable한 방법이 아닌게 되버리는것 같은데요. 음.. 이게 portable한 방법이 아닌건가요? 햇갈리는군요.
======================
BLOG : http://superkkt.com
======================
BLOG : http://superkkt.com
포인트는 "순서"가
포인트는 "순서"가 아니라 "오프셋"입니다.
--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)
--
Jun, Woong (woong at gmail.com)
http://www.woong.org
관계 있을듯한
관계 있을듯한 글입니다.
http://kldp.org/node/76375
___________________________________
Less is More (Robert Browning)
___________________________________
Less is More (Robert Browning)
일단.. C 로 밖에
일단.. C 로 밖에 개발할 수 없는 플랫폼이구요. 상속 구현시 부모 클래스의 멤버 변수 구조체를 자식 클래스에서 구조체 형태로 포함할 것인지 아니면 각 멤버변수들를 그대로 순서대로 먼저 나열할 것인지에 관한것입니다. 어차피 수작업으로 적는건 아니고 #define 을 이용해서 자동화해 놓았기 때문에 각 클래스의 멤버들만 정의하면 나머진 상속 구조대로 상위부터 순서대로 나열되게 해놓았습니다.
부모 멤버 변수를 구조체형태로 포함시키지 않고 변수들을 직접 순서대로 나열했을때 이점은 메소드에서 상속받은 멤버 변수를 사용할때에도 객체를 부모 구조체로 캐스팅하거나 super->... 와 같은 식이 아니라 c++.처럼 자기 멤버 변수 엑세스 할때와 똑같이 self-> 로 똑같이 접근할 수 있기 때문입니다. self 객체 캐스팅이나 어떤 부모 클래스에서 상속받은 멤버 변수인지 등에 대한 신경을 안 쓰도 되죠.
헌데 이렇게 하였을때 각 멤버들의 오프셋이 구조체 형태로 포함했을때와 달라지는 경우가 있을 수 있는가? 하는것이 질문의 요지입니다. 예제를 조금 더 쉽게 쓰보면 아래 A와 B가 항상 같은 결과인가? 하는것입니다.
위에서 이미 답변이
위에서 이미 답변이 나왔습니다. 다를 수 있습니다.
--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)
--
Jun, Woong (woong at gmail.com)
http://www.woong.org
조금 다른 이야기이지만
조금 다른 이야기이지만 관련이 있을까 해서 적어봅니다
IPv6 에 관련해서 새로 추가된 sockaddr_storage 가 비슷하게도
sockaddr, sockaddr_in, sockaddr_in6 로 서로 캐스팅해서 쓸 수 있습니다.
(http://www.faqs.org/rfcs/rfc2553.html 의 #3.10)
각각 구조체가
입니다.
> IPv6 에 관련해서
> IPv6 에 관련해서 새로 추가된 sockaddr_storage 가 비슷하게도
> sockaddr, sockaddr_in, sockaddr_in6 로 서로 캐스팅해서 쓸 수 있습니다.
>
http://kldp.org/node/72838
중간 bind 함수가 언급되는 곳부터 보시면 됩니다. 애초부터 잘못된 설계가
얼마나 긴 시간 영향을 줄 수 있는지 보여주는 대표적 예에 해당합니다.
p.s. 퇴근하고 싶네요 T.T
--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)
--
Jun, Woong (woong at gmail.com)
http://www.woong.org
아무리 자동화가
아무리 자동화가 되어있다고 한들... 언어자체에서 지원하지 않는 것을 하다보면...
시스템이 약해지지않을까요...^^; 나중에 에러나면 처리하기 무지어렵다던지...;;
OOP가 없는 세상은 이래서 별로 맘에 안듭니다 ^_^;;;
------------------------------------------
Let`s Smart Move!!
http://kalstein.tistory.com/
답변들
답변들 감사드립니다. 음..일단 표준엔 위배되므로 구현체따라 구조체 멤버의 옵셋이 바뀔수도 있으므로 이식성은 없다. 이렇게 생각하면 되겠군요.
만약 gcc 에선 항상 옵셋이 동일하게 처리한다고 가정하면 gcc를 사용하는 경우엔 옵셋이 안바뀐다고 봐도 될련지요?
위 질문과 별개로..말씀하신대로 공용체를 쓰는 방식으로 다음과 같은 했을때는 절대적으로 바뀌지 않는다고 봐도 될련지요.
댓글 달기