CnUnix

[알림판목록 I] [알림판목록 II] [글목록][이 전][다 음]
[ CnUnix ] in KIDS
글 쓴 이(By): zeo (ZeoDtr)
날 짜 (Date): 1994년02월07일(월) 10시08분26초 KST
제 목(Title): Re:re: 결론 by zeo



HellCat님.
우선 저의 의도적인 발언으로 감정을 상하셨다면 죄송합니다.
사실 저는 그동안 자기 실수나 무지의 소치인 것을 컴파일러 잘못으로 돌리는
사람들이 하도 많이 있어 왔기 때문에 (저도 그런 면이 있죠) 이 기회에 한마디
하고 싶었던 겁니다. 그런 의미에서 '의도적'이었다는 거죠.
거기에 HellCat님이 재수없게 걸려 드셨네요.

본론으로 들어가서,

다시 말하지만 TC는 잘못이 없습니다.
이에 관련해서 HellCat님께서 말씀하신 것을 귀찮을지도 모르지만 조목조목
짚어볼 필요가 있을 것 같습니다.

1
-------

HellCat님께서 다음의 예문을 들어 주셨는데요...
"Again, intermediate results can be stored in temporary variables
 to ensure a particular sequence."
애고, 어디 있는 말인지 말씀을 안해 주셔서 찾는데 좀 애를 먹었습니다.
바로 앞쪽(49쪽)에 있는 것도 모르고...
하여튼, HellCat님이 이 문장을 해석할 때 약간 오해를 하신 것 같습니다.
이 문장을 능동태(사역)로 바꿀 때의 주어는 "Compiler"가 아니라 "Programmer"
입니다. 즉, 임시변수를 만들어야 하는 것은 컴파일러가 아니라 프로그래머란
거죠. 미국말이 수동태가 많아서 이런 식의 오해가 많군요.

요 대목에서 또 하고 싶은 말들이 있습니다만 그것만으로도 글 하나를 쓸 정도가
되기 때문에 다음 기회에 쓰도록 하죠. (뭐 인간적인 비난 같은 이야기가
아니고요, technical한 문제입니다. 오해 없으시길...)

결론: 특정 expression의 경우, evaluation 순서는 여전히 믿을 수 없다.
      컴파일러 맘이다.
      꼬우면 임시변수를 써서 강제로 순서를 매겨라.

2
-------

HellCat님께서는 마치 function call의 경우에만 evaluation 순서를 믿을 수
없는 것처럼 말씀하고 계신데, 제가 애써 베껴 올린 것 중에 다음의 줄을
간과하신 것이 아닌지?

Function calls, nested assignment statements, and increment and decrement
(1)~~~~~~~~~~~  (2)~~~~~~~~~~~~~~~~~~~~~~~~~      (3)~~~~~~~~~~~~~~~~~~~~
operators cause "side effects"...

3
-------

또, 다음의 두 문장에서

result = a; /* a is expression */
func (a);   /* a is the same expression */

두개의 a가 다르게 evaluate되는 것을 비난하셨다고 하셨는데, 그것은 컴퓨터
세계를 너무 순진하게 보시는 것이 아닌지요?
1---에서 결론을 내렸듯이, 특정 expression의 경우, evaluation 순서는 믿을
수 없습니다. 이 말에는 특정 expression은 완전히 같은 expression을 2곳
이상에서 썼을 경우 (그것이 심지어는 같은 화일 안에서라도!) 다른 결과가
나오더라도 불평하지 말라는 뜻도 포함되어 있다고 봅니다. 즉, 컴파일러가
상황에 따라서 optimization을 위해 (혹은 단순히 취향때문에) evaluation
순서를 다르게 조정할 수도 있는 거죠.
너무한다고 할 지 모르지만 그게 삶이죠, 뭐.

4
-------

참고가 될까 해서 TCW와 MSC 7.0에서 나온 결과들을 적어 봤습니다.
순서는 C 코드, compile한 이후의 assembler 코드, 결과 순입니다.
여기서는 printf를 안쓰고 babo라는 argument한개짜리 함수를 간단히 썼습니다.

[TCW]

코드:  babo(++i + ++i)
asm :  inc si (i는 자동으로 register 변수 si로 지정됨)
       mov ax,si
       inc si
       mov dx,si
       add ax,dx
       push ax
       call _babo
       pop cx
결과:  3

코드:  z = ++i + ++i;
asm :  inc si
       inc si
       mov ax,si
       add ax,si
       mov di,ax (z는 자동으로 register 변수 di로 지정됨)
결과:  4

[MSC 7.0 - no optimization]

코드:  babo(++i + ++i)
asm :  add si,1 (i를 프로그램에서 강제로 register변수로 지정, si가 됨)
       mov ax,si
       add si,1
       mov cx,si
       add cx,ax
       push cx
       call _babo
       add sp,2
결과:  3

코드:  z = ++i + ++i;
결과:  위와 같은 asm코드가 나오고, 결과도 같은 3.

[MSC 7.0 - with -Ot option]

코드:  babo(++i + ++i)
asm :  mov ax,4 (코드를 훑어본 뒤 자동으로 constant화했다. 대단하다!)
       push ax
       call _babo
       add sp,2
결과:  4

코드:  z = ++i + ++i;
결과:  위와 같은 asm코드가 나오고, 결과도 같은 4.

---------

애고 힘들어...
아무튼, 여기서 교훈은 여전히
우리 모두 코딩 잘 합시다. 세상 모든 컴파일러들의 비위에 맞게...


                                   ZZZZZZ
                                     zZZ  eeee  ooo
                                    zZ    Eeee O   O
                                   ZZZZZZ Eeee  OoO
[알림판목록 I] [알림판목록 II] [글 목록][이 전][다 음]
키 즈 는 열 린 사 람 들 의 모 임 입 니 다.