shift 연산

Computing 2008.05.20 17:01
32비트 컴퓨터에서


위 코드의 출력값은 얼마일까?

제일 처음 떠오르는 답은 0x00000000 일 것이다.

조금 눈치가 빠른 사람이라면 0x00000000 이 상식적인 답이겠지만 답이 0x00000000 이 아니기 때문에 이런 문제를 내었으리라 짐작하고서는 뭔가가 있다고 생각할 것이다.

정말 뭔가가 있다.
컴파일을 하면,

$ gcc b.c
b.c: In function 'main':
b.c:7: warning: left shift count >= width of type

gcc 가 친절하게 warning 도 내어 준다.

실행을 시키면,
$ ./a.out
0x00000002

마치 circular shift된 것 같은 결과가 나온다.
왜 그럴까?

컴파일러가 << 연산의 operand 에 modular 연산을 취할까? 단지 << 연산인데, 그냥 shl 같은 instruction으로 곧장 매핑시키지 않고 modular연산 따위를 컴파일러가 할까? 아무래도 그건 오버하는 것 같다.

cpu instruction manual 을 살펴 보았다.


Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2B: Instruction Set Reference, N-Z 에서는 shift 연산에 대해서 아래와 같이 이야기하고 있다 :


The destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). A special opcode encoding is provided for a count of 1.

역시나, 컴파일러가 오버하는 것이 아니었다.
인텔은 그렇다 해도 다른 CPU, ppc 나 sparc 은 어떨까?
sun 과 aix 에서 테스트 해 본 결과 마찬가지 결과가 나왔다.
sparc v9 instruction set reference manual을 보아도 마찬가지 설명(마스크 아웃한다는)이 나와 있다.

우연히 찾은 것이지만, 재미있는 것이라고 생각되어서 한번 적어 보았다.

신고
tags : C/C++
Trackback 0 : Comment 0

Write a comment


DEBUG macro

Computing 2008.05.20 13:19
C 로 프로그래밍을 하는 사람이라면 거의 모두들 한번쯤 디버깅 메세지를 출력하는 문제에 대해 고민해 보았을 것이라 생각한다.
아마도 빌드 모드가 디버그일 경우에만 매크로가 확장되고, 릴리즈일 경우에는 사라지도록 다음과 같은 매크로를 정의해서 사용했을 것이다 :
그런데 위의 매크로를 쓰면서 불편한 것이 하나 있으니, 바로 다음과 같이 사용할 수 밖에 없다는 것이다 :
그렇다. 치명적인(!!!) 약점이 있으니, 바로 괄호를 두개 써야 한다는 것이다.

C99 표준에서 이 문제를 해결할 수 있도록 매크로에 가변 인자를 지원하는 기능(?)이 포함되었으나 그 표준정의 자체가 한계를 가지고 있는 데다가 (함수의 가변 인자와는 달리 반드시 최소 하나의 인자를 받아야만 한다는 제약사항이 있다) 지원하는 컴파일러마저, VC++ 2005 이상에서만 지원한다. 물론 gcc 는 당연히 지원하는 데다가 플러스 알파로, C99 표준의 약점을 해결하기 위한 확장까지 제공하긴 하지만, 여기서 내가 원하는 것은 모든 컴파일러에서 통용되는 방법이므로 매크로 가변인자 기능을 사용하기에는 무리가 있다.

그러면 보기 싫은 두개의 괄호를 어떻게 해결할까...

아래와 같이 DEBUG 매크로를 정의해 보자.
혹은
컴파일러의 최적화에 의존을 하게 되면 필요없는 printf 는 사라지게 된다. 게다가 요즘 컴파일러는 이정도의 최적화는 기본이다.

재미있는 것은, 아래의 것 보다, 함수 이름을 (void) 로 치환해 버리는 것인데,,,

그러면 위의 첫번째 방법을 사용했을 때 아래와 같은 코드는
프리프로세서를 거치고 나면, 디버그 모드에서는
디버그 모드가 아니면
로 확장되게 된다.

얼핏 보아서는 이게 컴파일이 될까 하는 생각이 들겠지만,
놀랍게도 컴파일이 된다! +_+ (콤마 연산자임)

정말 기발(!)하지 않은가?
나는 수년간 괄호 두개가보기 싫은데도 불구하고 달리 뾰족한 방법을 생각하지 못해서 괄호 두개를 계속 써 왔었는데, 저 방법을 보는 순간 갑자기 마구 억울해지기 시작했다.

물론, 아래의 다소 암호같은(!) (void) 로 치환하는 방법은 (댓글에서 han9kin 님이 지적했듯이) 콤마 연산자로 구분된 각각의 연산이 실행이 되어 버려서 변수의 값이 변할 수 있는 위험이 존재한다.

그러니 뭔가 특이한 걸 써서 "튀"기 보다, 안전하게 while (0) 로 치환하는 방법을 선택하도록 하자.

신고
tags : C/C++
Trackback 0 : Comments 2
  1. BlogIcon han9kin 2008.05.20 13:56 신고 Modify/Delete Reply

    #define DEBUG (void)

    #define DEBUG while (0) printf
    는 제가 보기에는 너무 달라보입니다.

    전자는 인자들에 대한 연산이 모두 실행될 것이고, 후자는 실행되지 않을 겁니다.
    물론 디버깅 정보 출력하는 코드에 연산이 있는 경우는 거의 없겠지만.

    그리고 gcc -W 로 전자를 컴파일하면 다음과 같은 워닝이 나와서 보기가 별로 안좋습니다.
    warning: left-hand operand of comma expression has no effect

  2. BlogIcon Orchistro 2008.05.20 17:04 신고 Modify/Delete Reply

    저도 그래서, 위의 (void) 로 치환한 것은 흥미거리 정도로 생각합니다 :-) 실제는 아래의 while(0) 을 쓰는 것이 나으리라 생각됩니다 :-)

Write a comment


kicking the tires

English 2008.05.20 11:24
John McCain 이 지난 토요일 (2008. 5. 17) TV 토크쇼에 나와서 한 우스갯소리인데,,,
님 좀 짱인듯 ㅋㅋㅋ

If come November, you still haven't decided, I'd be willing to set aside my differences with your party and say,

"Hey, let's put both of them on the ballot."

I'll support you on that, it's the least I can do.
In conclusion, I wanna add that I also thought John Edwards had a lot of good ideas.
And you might wanna kick the tires on him one more time.

kicking the tires : an expression, probably came from buying a used car, when it was often advisable to kick the tires to see if they are old and flabby. The tires are an extra expense that you don't want to take on.
The meaning has broadened into a general saying now. It means "test it out", "check it out for flaws or errors", "try before you buy." If you are walking around a car lot, window shopping, a salesman may come up to you and say, "Do you want to kick the tires?" He doesn't mean that you should actually kick the tires. He means, "do you want to sit in it / ask questions about it / take it out for a test drive?"
신고
Trackback 0 : Comment 0

Write a comment


깔끔하게 소스 코드 보기

Computing 2008.05.20 10:24
신택스 하일라이터를 쓰는 방법

자세한 내용은 http://gyuha.tistory.com/193 를 참조.

http://code.google.com/p/syntaxhighlighter/

테스트 :


Configuration option

These options allow you to individually configure text blocks.

nogutter Will display no gutter.
nocontrols Will display no controls at the top.
collapse Will collapse the block by default.
firstline[value] Will begin line count at value. Default value is 1.
showcolumns Will show row columns in the first line.

The options are passed together with the alias and are separated by a colon : character.

<pre name="code" class="html:nocontrols:firstline[10]">
... some code here ...
</pre>
신고
Trackback 0 : Comment 0

Write a comment


뜨거운 것이 좋아

잡동사니 2008.05.10 04:35
얼마나 오래 전인지는 기억이 매우 흐릿하지만, 김민희라는 배우(?)... 라고 해야 할지 모델이라고 해야 할지 아리송한 처자가 TV 화면에 좀 어른거리던 때가 있었다. 바람불면 날아갈 것 같은 마른 체형과 이상하게 끌리는 얼굴때문에 처음에 좀 관심을 가졌다가, 엄청난 내공의 국어책읽기 대사를 보고선 그냥 '훗 -_,-' 하는 실소를 자아내게 했었던 탤런트이다. 잠시 브라운관에서 보이는 듯 하더니 어느샌가 사라져버렸었다.

정말 심심하던 차에 시간 죽이기 용으로 볼만한 영화가 없는지 여기저기 돌아다니다가 "뜨거운 것이 좋아"를 봤다. 물론, 원더걸즈의 영향이 없었다고는 못하겠다. 약간 므흣 *-_-* 한 것을 하나도 기대하지 않았다고는 못하겠다. 아무튼, 영화를 보게 되었는데....

깜짝 놀랐다.
"용의주도 미스 신"을 본 직후에 보아서 더욱 놀랐던 것인지도 모르겠다. (용의주도 미스신은 정말 용의주도하게 개판으로 만든 영화였다. 예슬쒸~~~ 시나리오 좀 보고 골라서 출연하셈. 물론 지금이야 그럴 형편이 아니기도 하겠지만...;)

처음에 담배를 빡빡 피면서 꽥꽥거리는 모습을 보고는 "어라, 어디서 많이 본 얼굴인데..." 라는 생각이 문득 들었다.
캐스팅 목록에 김민희가 있었던 것을 상기해 내고는, "아하, 김민희였네" 라고 생각했다. (주연이다! 주연! 포스터를 보니 한 가운데에 떡 있구나!)

뜨거운 것이 좋아


영화를 계속 보면서

'이 김민희가 그 김민희 맞나? 동명 이인인 연기 잘하는 신인인가? 설마~ 에에에???'

하는 생각이 머릿속을 떠나지 않았다.

영화도 그럭저럭 괜찮았다 (알고 봤더니 "싱글즈" 와 감독이 같았다).
이미 내 나이가 영화에서 그려지는 주인공의 연령대보다 훨씬 더 많아져서 그런지, 큰 울림은 없었지만, 저만하면 약간 모자란 수작정도는 되겠더라. 무엇보다, 김민희라는 탤런트가(이제 배우라고 해도 될려나?) 이만큼 컸구나 하는 걸 볼 수 있어서 반가운 영화 되겠다.

신고
tags : 영화
Trackback 0 : Comment 0

Write a comment

티스토리 툴바