[완료] 로컬 integer형 변수에 assign한 값이 적용되지 않습니다.
안녕하세요.
윈도우와 모바일 환경에서만 작업을 하다가, 리눅스 깔고 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 옵션을 추가하였습니다.)
답변 부탁드립니다. 감사합니다.
아마 나눗셈 연산을 빨리 하실려고 쉬프트 하신 것 같은데..
>>중간에 있는 TRACE 문에서 변수를 찍어보는데, [p6.x]와 [(p4.x+p5.x)>>1] 의 값이 다르게 나옵니다. 변수에 저장된 값이 터무니 없는 값으로 나오고 있습니다.
>>그리고 위 코드를 트레이스로 지나가면, 제대로된 값이 들어가네요.
-------------------------------------------------------------
먼저 이 글이 무슨 뜻인지 정확한 의미를 모르겠구요
두 경우 모두 curve* orgCubic, curve* pC1, curve* pC2
값이 같았는지 궁금하구요.
제가 해 드릴 수 있는 말은
p4.x = ((p1.x+p2.x)>>1)&0x7FFFFF;
로 바꾸어서 실행시켜 보시라는 것입니다.
저도 옛날에 쉬프트 연산할때 이런 현상 때문에 약간 곤란을 겪었던
기업이 있습니다.
계산된 값은 제대로 나오고요...
모바일용 2D 그래픽 엔진의 함수 일부 입니다. orgCurve를 2개의 curve로 나누는 함수 이고요(pC1, pC2 는 out value)
항상 동일한 값(orgCurve)으로 테스트를 했고, 함수내의 p6.x 의 값이 잘못 들어값니다.
나머지 변수(p1~p5,p6.y)에는 제대로 들어가고요,
TRACE 윗줄의 p6.x의 값이 바뀌면서, 이하 값들이 모두 꼬이는 상황입니다.
codepage 님의 조언
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
코드상의 문제는 아닐꺼라 보여지고요..
동일 코드로 다른 플랫폼에서는 잘 동작 하고 있고요.
리눅스 환경에서만 오동작이 일어나고 있는 부분입니다.
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이 안나오고 다른 값들이 들어가 있네요.
저의 무지함이 탄로 나는군요 -.,-
질문했던 사람입니다.
warning level을 높혀서 컴파일을 해보니, multiline comment 경고가 뜨네요.
별 생각없이 지나쳤던 부분이었는데, 해당 부분을 제거해 보니 정확히 그래프가 나옵니다.
예전에도 비슷한 경험이 있어서, 컴파일 옵션 오류라고만 생각했던것이 이틀을 까먹었군요.
그런데, 이것이 표준 C 컴파일러의 결과인가요?
지금까지, VC6, 2003, 2005, EVC 4.0, ADS 1.1, ADS1.2, RVCT 2.2 등등을 사용했었는데, 다 통과되던 코드라서 조금 의아하네요.
해결되었다니 정말
해결되었다니 정말 다행이군요. ^o^
shift연산과 관련한 문제가 있을까 싶어 잠깐 인터넷 서치를 해 봤는데 모토롤라CPU 관련 옵션에서 large shift 관련 내용이 나오고 몇가지 SDL 관련 링크 순서에 대한 내용은 있었지만 딱히 없어서.. 저도 참 궁금 했었습니다.
호기심이 많아서 죄송스럽습니다만, 'multiline comment 경고' 가 나왔던 부분을 좀 보여주실 수 있으신지요?
-------------------------------------------------
$yes 4 8 15 16 23 42
-------------------------------------------------
$yes 4 8 15 16 23 42
댓글 달기