윈도우 네트워크 프로그래밍 중 발생한 warning C4761

 윈도우에서 네트워크 프로그램 소스를 컴파일 하던 중 이상한 warning 을 발견하였다.


C:Documents and SettingsOwnerMy DocumentsNetworkhelloworld_client_winhelloworld_client_win.c(34) : warning C4761: integral size mismatch in argument; conversion supplied
 문제의 소스 부분은 다음이었다.

servAddr.sin_port = htons(atoi(argv[2]));
 보기에는 문제가 없는 부분이다. 정상작동하는 소스였다.(..리눅스에서 확인)

 물론 warning 을 무시하고 링크를 하여도 문제없이 프로그램을 잘 실행되었다.

 그렇다면 무엇이 문제일까….먼저 C4761 에 관한 내용을 찾아 보았다.

 다음과 같은 내용을 찾을 수 있었다.



Compiler Warning (level 1) C4761

integral size mismatch in argument : conversion supplied


The base types of the actual and formal parameters of a function were different.


The compiler converted the actual parameter to the type of the formal parameter.

 관련 링크 : http://msdn2.microsoft.com/en-us/library/aa733937(VS.60).aspx

 내용인즉 인자의 사이즈가 맞지 않는다는 것이다.

 다시 소스를 살펴보다가 다음을 발견하였다.


unsigned short__cdecl htons(unsigned short)
 즉 인자값으로 short 형이 와야 하는 것이다. 하지만 atoi() 함수는 리턴형이 int 값이므로 여기서 형변환의 문제가 생긴 것이다.

 다음과 같이 고쳐주니 warning 이 사라지고 깔끔한 컴파일이 되었다.


servAddr.sin_port = htons((unsigned short)atoi(argv[2]));

SICP 연습문제 1.10

 연습문제 1.10

 다음 프로세스를 이용하여 f, g, h 프로시저의 기능을 수학으로 정의하는 문제이다.

(Language : text)
  1. (define (A x y)
  2.     (cond ((= y 0) 0)
  3.         ((= x 0) (* 2 y))
  4.         ((= y 1) 2)
  5.         (else (A (- x 1) (A x (- y 1))))))

사용자 삽입 이미지
 프로시저 실행 문제의 답은 위와 같다.

 실질적인 문제는 바로 다음인데…..나는 노가다(?)로 풀었다.
 

(Language : text)
  1. (define (f n) (A 0 n))
  2.  
  3. (define (g n) (A 1 n))
  4.  
  5. (define (h n) (A 2 n))

 (f n) 의 경우

(Language : text)
  1. (f 1) = 2
  2. (A 0 1) = 4
  3.  
  4. (f 2) = 4
  5. (A 0 2) = 4
  6.  
  7. 즉 (f n) = 2n

 (g n)의 경우

(Language : text)
  1. (g 1) = 2
  2. (A 1 1) = 2
  3.  
  4. (g 2) = 4
  5. (A 1 2)
  6. (A 0 (A 1 1))
  7. (A 0 2) = 4
  8.  
  9. (g 3) = 8
  10. (A 1 3)
  11. (A 0 (1 2))
  12. (A 0 (A 0 (A 1 1)))
  13. (A 0 (A 0 2))
  14. (A 0 4) = 8
  15.  
  16. 즉, (g n) = g^n

 (h n)의 경우

(Language : text)
  1. (h 1) = 2
  2. (A 2 1) = 2
  3. (h 2) = 4
  4. (A 2 2)
  5. (A 1 (2 1))
  6. (A 1 2)
  7. (A 0 (A 1 1))
  8. (A 0 2) = 4
  9. (h 3) = 16
  10. (A 2 3)
  11. (A 1 (A 2 2))
  12. (A 1 (A 1 (A 2 1)))
  13. (A 1 (A 1 2))
  14. (A 1 (A 0 (A 1 1)))
  15. (A 1 (A 0 2))
  16. (A 1 4)
  17. (A 0 (A 1 3))
  18. (A 0 (A 0 (A 1 2)))
  19. (A 0 (A 0 (A 0 (A 1 1))))
  20. (A 0 (A 0 (A 0 2)))
  21. (A 0 (A 0 4))
  22. (A 0 8) = 16
  23. (h 4) = 65536
  24. (A 2 4) = 65536
  25. 즉, (h n) = 2^(A 2 n-1)

SICP 연습문제 1.9

 연습문제 1.9
 

(Language : xml)
  1. (define (+ a b)
  2.     (if (= a 0)
  3.         b
  4.         (inc (+ dec a) b))))
  5.  
  6. (define (+ a b)
  7.     (if (= a 0)
  8.         b
  9.         (+ (dec a) (inc b))))

 같은 프로시져가 있을 때, 각각의 프로시저가 (+ 4 5)를 계산한다고 한다면 반복 프로세스인지 재귀 프로세스인지를 알아보는 문제이다.

 솔직히 처음에 이 문제를 봤을때…둘다 재귀인 줄 알았다.

 프로시저가 끝나기 전에 자신을 호출하고 호출하고….하지만 이것은 C언어가 아니었다.

 역시나 한참을 헤매이다…노슈님의 블로그에서 해답을 찾았다.

 관련 링크 : http://nosyu.egloos.com/4058585

  첫 번째 프로시저의 실행 순서이다.

(Language : text)
  1. (+ 3 4)
  2.  
  3. (inc (+ 2 4))
  4. (inc (inc (+ 1 4)))
  5. (inc (inc (inc (+ 0 4))))
  6. (inc (inc (inc 4)))
  7. (inc (inc 5))
  8. (inc 6)
  9.  
  10. 7

 두 번째 프로시저의 실행 순서이다.
 

(Language : text)
  1. (+ 3 4)
  2. (+ 2 5)
  3. (+ 1 6)
  4. (+ 0 7)
  5.  
  6. 7

 역시나 실행 순서를 보면 한눈에 들어온다.

 즉, 첫 번째 프로시저는 재귀 프로세스(되도는 프로세스)이고, 두 번째 프로세스는 반복하는 프로세스이다.

사용자 삽입 이미지

리눅스에서 쓰레드의 ID 확인시 주의할 점.

 리눅스에서 쓰레드를 생성하여 ID 값을 찍어볼때….

다음과 같이 마이너스 값이 나오는 경우가 있다.

사용자 삽입 이미지
 이와 같은 경우는 printf의 타입 값을 잘못 지정해서 생기는 현상이다.

 보통은 다음과 같이 입력했을 것이다.

(Language : c)
  1. pthread_t t_id;
  2.  
  3. state = pthread_create(&t_id, NULL, thread_function, NULL);
  4.  
  5. printf(“생성된 쓰레드의 ID : %d n, t_id);

 하지만 pthread_t 의 타입을 보면…
 
사용자 삽입 이미지
 즉…..%lu 로 지정해야 정상적인 값이 나온다.

(Language : c)
  1. pthread_t t_id;
  2.  
  3. state = pthread_create(&t_id, NULL, thread_function, NULL);
  4.  
  5. printf(“생성된 쓰레드의 ID : %lu n, t_id);

 정상적인 출력 값
 
사용자 삽입 이미지

SICP 연습문제 1.8

 참으로 허무한 문제다.

 분명 나의 계산에는 이상이 없었다.

 보고 또 보고, 계속 봐도 나는 틀린게 없었다.

 뭐가 문제지?

 답은 책이 잘못된 것이었다…..

 관련 링크 : http://www.buggymind.com/72

 한참을 끙끙대다가 인터넷의 도움을 받기로 하고 검색한 결과 어이없는 내용없다…(하하…)

 문제인즉, 세제곱을 구하는 공식이 틀렸던 것이다.

 아래의 공식이 정확한 공식이다.

사용자 삽입 이미지
 아래는 바뀐 코드 내용이다.

사용자 삽입 이미지