32bit CPU 인 ARM 에서 개발하고 있을때, 


아래와 같이 64비트 변수를 사용하려고 u_int64_t 타입을 사용할 경우, 문제 없이 동작되기를 기대하겠지만 잘 안되는 경우가 많다. 

 
#include <stdio.h>
#include <sys/types.h>


int main(int argc, char *argv[])
{
    u_int64_t value1;
    
    value1 = 0xffffffffffffffff;
    
    printf("%lld\n", value1);
    return 0;
}


위 코드를 아래처럼 컴파일을 해 보면



$ arm-none-linux-gnueabi-gcc -Wall -Werror -o test test.c cc1: warnings being treated as errors test.c: In function 'main': test.c:9: error: integer constant is too large for 'long' type


위와 같이 에러가 발생한다. 물론 -Werror 옵션을 제거하면 Warring 은 뜨겠지만 빌드는 될 것이다. 


uint64_t 타입은 

#typedef unsigned long long int uint64_t 

 으로 만드는데 C90 표준은 아니고 C99 에서야 지원하기 시작한 상황이다.그래서 빌드시 어떤 표준을 사용할 것인지에 대해 명시해 주어야 한다.  



아래와 같이 C99 표준 지정하여 빌드하면 문제없이 처리된다. 

$ arm-none-linux-gnueabi-gcc -Wall -Werror  -std=gnu99 -o test test.c



ARM 쪽에서는 잘 빌드 되었는데, 이젠 X86_64 에서 printf 사용시 문제가 발생한다. 


위의 에러 메시지에서 볼 수 있듯이 


32bit 머신에서 uint64_t 는 unsinged long long int 인데,

64bit 머신에서 uint64_t 는 unsigned long int 이므로 


printf("out : %lld\n", value); /* 32bit 머신에서는 OK, 64bit 머신에서는 fail */

printf("out : %ld\n", value); /* 32bit 머신에서는 fail, 64bit 머신에서는 OK */

 

인 상황이 벌어지게 된다. 


우선 stdint.h 를 참조하여 코드를 아래와 같이 묶어 주었다. 




 
#include <stdio.h>
#include <sys/types.h>


int main(int argc, char *argv[])
{
    u_int64_t value1;
    
    value1 = 0xffffffffffffffff;
    
#if __WORDSIZE == 64
    printf("%ld\n", value1);
#else
    printf("%lld\n", value1);
#endif
    return 0;
}

위와 같은 방식을 사용해도 되고 아래처럼 type casting 을 사용해도 된다. 아래 방식이 더욱 안정적으로 동작할 것이다. 



#include <stdio.h> #include <sys/types.h> int main(int argc, char *argv[]) { u_int64_t value1; value1 = 0xffffffffffffffff; printf("%lld\n", (long long unsigned int)value1); return 0; }



이런 문제는 특히, 멀티플랫폼을 지원하는 SW 개발시에 발생할 가능성이 크다. 처음부터 멀티 플랫폼 지원을 예상하여 작성하면  향후 알 수 없는 문제 발생을 줄일 수 있다. 




'development' 카테고리의 다른 글

[driver] ipTime N150UA-4dBi  (8) 2014.09.16
[program] unused variable 문제  (0) 2013.08.02
[u-boot] RPC : sendmsg returned error 101  (0) 2013.07.19
[Kernel] Kbuild system  (0) 2013.07.12
[kernel] __read_mostly?????  (0) 2013.05.08
블로그 이미지

김유석0

,