[완료] 로컬 integer형 변수에 assign한 값이 적용되지 않습니다.

paraya의 이미지

안녕하세요.

윈도우와 모바일 환경에서만 작업을 하다가, 리눅스 깔고 SVN 설치하면 삽질을 하고 있습니다.

한컴리눅스/NetBeans 환경에서 기존 소스를 이용해서 프로젝트를 만들고 실행까지 완료를 한 상황인데, 결과물이 다르게 나오고 있습니다.

----------------------------------------------
bool abc(curve* orgCubic, curve* pC1, curve* pC2)
{
point p1, p2, p3, p4, p5, p6;

p1.x = orgCubic->a1.x + orgCubic->c1.x + 1;
p1.y = orgCubic->a1.y + orgCubic->c1.y + 1;
p2.x = orgCubic->c1.x + orgCubic->c2.x + 1;
p2.y = orgCubic->c1.y + orgCubic->c2.y + 1;
p3.x = orgCubic->c2.x + orgCubic->a2.x + 1;
p3.y = orgCubic->c2.y + orgCubic->a2.y + 1;

p4.x = (p1.x+p2.x)>>1;
p4.y = (p1.y+p2.y)>>1;
p5.x = (p2.x+p3.x)>>1;
p5.y = (p2.y+p3.y)>>1;
p6.x = (p4.x+p5.x)>>1;
p6.y = (p4.y+p5.y)>>1;

TRACE(("p6.x = %d, assign = %d", p6.x, (p4.x+p5.x)>>1));

......


return TRUE;
}
-------------------------------------------------
중간에 있는 TRACE 문에서 변수를 찍어보는데, [p6.x]와 [(p4.x+p5.x)>>1] 의 값이 다르게 나옵니다. 변수에 저장된 값이 터무니 없는 값으로 나오고 있습니다.
그리고 위 코드를 트레이스로 지나가면, 제대로된 값이 들어가네요.

caller는 C++ 코드이고, 위 소스는 c base 입니다.

예전에 ARM9 코드를 ARM11 로 포팅할때도 위와 비슷한 현상이 있었는데(그때는 파라메터가 6개를 초과할경우, 이후 파라메터의 값이 쓰레기로 채워지는 현상), 당시에는 ARM 컴파일러에서 옵션을 변경해가면서 테스트해서 수정을 했었습니다.

SDL 기반으로 프로젝트가 되어있고, WIN32 SDL 프로젝트에서는 정상 동작을 합니다.
또한, 기존 소스는 WIN32, WINCE ARMV4I/MIPSII, ARM7/9/11 skt/lgt wipi 환경에서 잘 돌아가는 소스입니다.

gcc -c -g -D__DEBUG__ -D__FIXED32__ -D__PNG__ -D__LINUX__ -I../../inc -o curve_access.o curve_access.c

컴파일 옵션은 Netbeans 기본 옵션을 사용하고 있습니다. 컴파일러 버전은 gcc 4.1.1 20061120 자 입니다.

링크 옵션은..
g++ -o dist/Debug/GNU-Linux-x86/sdl_test build/Debug/GNU-Linux-x86/newmain.o -L/usr/lib -L/lib -lSDL -lSDLmain -Xlinker --start-group ../modules/lib/interface_linux_x86.a ../modules/lib/lib_linux_x86.a ../modules/lib/ws_linux_x86.a ../modules/lib/commonctrl_linux_x86.a ../modules/lib/svg_linux_x86.a ../modules/lib/svg_ui_linux_x86.a -Xlinker --end-group

(lib 순서를 맞추지 않으면 안되서..-Xlinker 옵션을 추가하였습니다.)

답변 부탁드립니다. 감사합니다.

codepage의 이미지

>>중간에 있는 TRACE 문에서 변수를 찍어보는데, [p6.x]와 [(p4.x+p5.x)>>1] 의 값이 다르게 나옵니다. 변수에 저장된 값이 터무니 없는 값으로 나오고 있습니다.
>>그리고 위 코드를 트레이스로 지나가면, 제대로된 값이 들어가네요.
-------------------------------------------------------------
먼저 이 글이 무슨 뜻인지 정확한 의미를 모르겠구요
두 경우 모두 curve* orgCubic, curve* pC1, curve* pC2
값이 같았는지 궁금하구요.

제가 해 드릴 수 있는 말은
p4.x = ((p1.x+p2.x)>>1)&0x7FFFFF;
로 바꾸어서 실행시켜 보시라는 것입니다.
저도 옛날에 쉬프트 연산할때 이런 현상 때문에 약간 곤란을 겪었던
기업이 있습니다.

paraya의 이미지

모바일용 2D 그래픽 엔진의 함수 일부 입니다. orgCurve를 2개의 curve로 나누는 함수 이고요(pC1, pC2 는 out value)

항상 동일한 값(orgCurve)으로 테스트를 했고, 함수내의 p6.x 의 값이 잘못 들어값니다.
나머지 변수(p1~p5,p6.y)에는 제대로 들어가고요,
TRACE 윗줄의 p6.x의 값이 바뀌면서, 이하 값들이 모두 꼬이는 상황입니다.

brucewang의 이미지

codepage 님의 조언 내용은 signed integer를 shift 연산할때 MSB 최상위 비트 즉 +/- 사인 비트의 문제를 확인해 보시기를 말씀하셨던 것 같습니다.

계산 결과값은 제대로 나오는데 그 값을 저장한 것은 잘못됬다는 것인가요?
해당 밸류의 maximum 값이 궁금하네요.. 혹시 type casting이 일어나면서 truncate 되는 것은 없는지..

(죄송합니다. 코멘트좀 추가 했습니다.)
저도 예전에 이런 유사한 경험이 몇번 있습니다. 특정 코드 아래부터 결과가 이상해 지는... 저의 경우는 dummy code를 넣어두면 그런 문제가 없어지기도 해서 그때는 뭔가 compiler상에 문제가 있는게 아닐까 했는데, 그당시는 제가 바이너리 코드 분석이 어려워서 그냥 넘어 갔었는데요, 저도 다른분들 의견 보면서 좀 배웠으면 합니다..

-------------------------------------------------
$yes 4 8 15 16 23 42

-------------------------------------------------
$yes 4 8 15 16 23 42

paraya의 이미지

동일 코드로 다른 플랫폼에서는 잘 동작 하고 있고요.

리눅스 환경에서만 오동작이 일어나고 있는 부분입니다.
TRACE로 찍는 부분에서, 계산값과 바로 두줄위에서 변수에 assign 한 값이 틀리게 나오는 경우네요.

변수는 4byte integer이고, 고정소숫점 16.16을 사용합니다.
계산 결과는 200 * 65536(16bit shift) 정도 이고, p6.x에 장되어있는 값은 48 이라는 값이 주로 들어가 있습니다 -,.-
정수의 max값은 15bit 정수 32767 정도 나옵니다.

아마도 결론은 컴파일 옵션을 조정하면서 수정이 될듯 한데...
이것이 c/c++ 혼용에서 나오는 것인지, 뭔지를 전혀 모르겠네요.

------------ trace 결과 입니다 -------------
p6.x = 16384002, assign = 21299201
p6.x = 13926402, assign = 15667201
p6.x = 15360002, assign = 20172801

코드를 수정하다보니, 48이 안나오고 다른 값들이 들어가 있네요.

paraya의 이미지

질문했던 사람입니다.

warning level을 높혀서 컴파일을 해보니, multiline comment 경고가 뜨네요.
별 생각없이 지나쳤던 부분이었는데, 해당 부분을 제거해 보니 정확히 그래프가 나옵니다.

예전에도 비슷한 경험이 있어서, 컴파일 옵션 오류라고만 생각했던것이 이틀을 까먹었군요.

그런데, 이것이 표준 C 컴파일러의 결과인가요?
지금까지, VC6, 2003, 2005, EVC 4.0, ADS 1.1, ADS1.2, RVCT 2.2 등등을 사용했었는데, 다 통과되던 코드라서 조금 의아하네요.

brucewang의 이미지

해결되었다니 정말 다행이군요. ^o^

shift연산과 관련한 문제가 있을까 싶어 잠깐 인터넷 서치를 해 봤는데 모토롤라CPU 관련 옵션에서 large shift 관련 내용이 나오고 몇가지 SDL 관련 링크 순서에 대한 내용은 있었지만 딱히 없어서.. 저도 참 궁금 했었습니다.

호기심이 많아서 죄송스럽습니다만, 'multiline comment 경고' 가 나왔던 부분을 좀 보여주실 수 있으신지요?

-------------------------------------------------
$yes 4 8 15 16 23 42

-------------------------------------------------
$yes 4 8 15 16 23 42

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.