구조체 패딩 문의

munhoney의 이미지

안녕하세요

구조체 패딩관련하여 몇가지 의문사항이 있어서 문의드립니다.

시험 목적은 윈도우 VC++에서 사용한 구조체를 Linux로 네트워크를 통한 전달시 문제가 발생하여
같은 구조체 패딩 구조를 갖고자 합니다.

예를 들면,

#include <stdio.h>
 
typedef struct data1 {
	int a;
	double b;
	int c;
} data1;
 
int main()
{
	printf("size : %d \n", sizeof(data1));
	return 0;
}

이와 같은 경우
VC++을 통해 컴파일하면,
size : 24

와 같이 나오고

Linux에서 하면
size : 16
이 나오지요.

물론 X86계열에서 테스트한 것입니다.

문제는 윈도우 시스템에서 VC++로 한 pack 구조를 그대로 리눅스에서 사용하고 싶다는 것입니다.

이를 위해 gcc 4.2(?) 버전을 사용하고 있는데,
컴파일 옵션중에 -fpack-struct=8로 하면 될 것 같은데 문제는 4까지만 되더군요. 원래 8을 안되는 건가요?
(#pragma pack(8)도 해보았으나 마찬가지네요.)

혹, 리눅스 시스템에서 size : 24로 나올 수 있는지요. 구조체 항목마다 __attribute__(aligned(8)) 로 사용하면 되겠지만,
실제 프로젝트에서는 구조체가 너무 많아서 이렇게 하기에는 역부족입니다.

좋은 방법있으시면 알려주세용~~~

clique의 이미지

구조체를 바로 네트웍으로 보내는 것은 권장되지 않는 통신 방법입니다.
(사실 권장 수준이 아니라, 컴파일러나 실행 환경에 따라 언제대로 오류가 날 가능성이 있죠)

구조체의 alignment는 굉장히 시스템에 의존적이기 때문이죠.

그러므로 네트웍 상에서 구조체를 주고 받으려면 serialize/deserialize 과정을 필요로 합니다. 물론, byte-order도 조정해야 하고요. serialize/deserialize 방법은 검색해보시면 많이 나옵니다.

munhoney의 이미지

네 먼저 답변 감사합니다. 하지만, 현재 프로젝트가 임베디드 프로젝트인데 serialize/deserialize 과정은 C#,Java같은 곳에서만 가능한것 아닌지요.
그리고 한 쪽은 이미 고정이 되어서 받는 다른 한 쪽에서 이를 맞추어야 하는 이상한 꼴(?)이 되어서요.

다른 방법은 없을까요?

---------------------------------
http://blog.naver.com/munhoney
---------------------------------

clique의 이미지

serialize/deserialize는 C#, java 등에서는 언어 혹은 라이브러리에서 지원합니다만, c는 직접해야 한다는 점 빼고는 별로 차이가 없습니다. 예를들면 아래와 같이요...

//serialize
memcpy(&sebuf[0], &st.a, 4);
memcpy(&sebuf[4], &st.b, 1);
memcpy(&sebuf[5], &st.c, 4);

// send data
send(fd, sebuf, 9, ...)

// recv data
recv(fd, dsebuf, 9, ...)

//deserialize
memcpy(&st.a, &dsebuf[0], 4);
memcpy(&st.b, &dsebuf[4], 1);
memcpy(&st.c, &dsebuf[5], 4);

ymir의 이미지

그냥 변수로 padding 을 넣어버리면 되지 않을까 싶네요.

typedef struct data1 {
    int a;
    char pad1[4];  /* just padding, not used */
    double b;
    int c;
    char pad2[4];  /* just padding, not used */
} 

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

munhoney의 이미지

그 방법은 가장 최후에 할려고 남겨두고 있습니다. ^^''

왜냐하면 한쪽이 이미 개발이 완성이 되었고, 바꿀 구조체가 어마어마하거덩요.
메뉴얼하게 바꾸는 것도 정말 시간이 많이 걸릴것 같구요..

다른 방법은 없을까요?

---------------------------------
http://blog.naver.com/munhoney
---------------------------------

ymir의 이미지

i386, x86_64 라면 -malign-double 을 주면 double 을 기준으로 align 이 이루어질겁니다.
(추가 : double 이 포함된 구조체에 한해서 그렇게 되네요..)

다만, 그렇게 되면 ABI 와 맞지 않게 되기 때문에..
같은 플랫폼에서 이 옵션을 쓰지 않은 appl 과의 호환성이라던가..
빌드 관련 문서가 따라다녀야 해서.. 유지보수가 귀찮아질 수도 있습니다.
(코드만 보고 작업할 경우 의도하지 않은 miss 가 발생할 수도 있구요)

가급적.. 애초에 padding 이 일어나지 않도록 설계를 하거나..
명시적으로 padding 을 넣어서 묵시적인 padding 이 일어나지 않게 하는게..
좀 더 낫지 않을까 생각되네요.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

munhoney의 이미지

아. -malign-double이 있었군요... 감사합니다. ^^
확인해보니 잘 되네요.

그런데.. 혹시 특정 struct에서만 국한하여 할 수도 있을까요? 그러면 전체적인 부분은 ABI가 맞아서 다름 appl과 문제가 없을 것이고
특정 부분 (네트워크로 전달시키는 부분)만 이 옵션을 사용할 수 있을것 같은데요..

아무튼 궁금한 점은 해결 되었습니다. 너무 감사합니다.

---------------------------------
http://blog.naver.com/munhoney
---------------------------------

vuccell의 이미지

삭제

gardner의 이미지

.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.