2016-07-15 4 views
1
typedef struct a{ 
    uint32 val1; 
    }A; 

typedef struct b{ 
    uint16 copy_val1; 
}B; 


void function1(A input) 
{ 
    B my_input; 

    my_input.copy_val1 = (uint16) input.val1; <-- Is this clean? 
} 

처음에는 구조체 a가 설계되었을 때 val1에는 두 개의 16 비트 값이 포함될 것으로 생각되었습니다. 그러나 우리는 하나의 16 비트 만 사용하기로했습니다.C typecasting uint32 to uint16

이제 메모리를 절약하기 위해 copy_val1의 유형을 uint32에서 uint16으로 변경합니다. 깨끗한 방법으로 타입 변환하고 val1의 16 비트 값을 copy_val1로 복사해야합니까?

OS는 MIPS 아키텍처의 vxworks입니다.

+0

코드가 작동하지 않습니까? 이 같은 주조는 괜찮을 것입니다. – Caius

+1

MIPS는 정렬에 매우 민감하며 컴파일러는 구조체 (패딩)의 요소를 레이아웃하는 방법을 많이 가지고 있으므로 팩을 채우지 않으면 메모리가 전혀 저장되지 않을 수 있습니다. 또한 내 경험에 비추어 볼 때 이것은 장기적으로 메모리 문제로 당신을 도울 수없는 마이크로 최적화의 일종입니다. 사실 IMHO는 매우 특정한 크기에 맞출 필요가없는 정수 값을위한 유형의 가장 좋은 선택은 그냥 보통 int (주목할만한 예외 : AVR과 같은 8 비트 아키텍처, int8_t는 정상적인 기본 선택 임) . – datenwolf

+0

빡빡한 메모리로 당신을 도울 수있는 더 중요한 트릭이 있습니다 : 어딘가에'char memory_reserve [SIZEOF_MEMORY * 5/100];를'.bss' 섹션에 넣습니다. 즉, 프로젝트에 사용할 수있는 메모리의 5 % 결국 몇 달 후에, 긴 밤과 대량 메모리에서 작동하는 일부 알고리즘에서 사용되는 배열의 마지막 비트를 압축하기위한 모든 노력의 결과로 예비 메모리에서 일정량의 메모리를 제거하여 하루를 절약 할 수 있습니다. – datenwolf

답변

1

단순히 uint32 값을 캐스트없이 uint16 변수에 할당하면됩니다.

그러나 자르기 위험이 있습니다. 할당 전에 val1 > UINT16_MAX인지 확인하십시오.

하나 또는 두 개의 기계 레지스터보다 큰 구조의 경우 구조에 포인터를 전달해야합니다. 그렇지 않으면 잠재적으로 큰 사본이 생성됩니다. 그러나 의미론의 변화를 주목하십시오.

+0

이면 충분합니까? 16 비트 값을 포함하는 비트가 복사되고 모든 0이 아닌 것을 보장합니까? val1에 저장된 값은 현재 16 비트 만 사용하고 있습니다. 그래서 나는 "절단의 위험"으로 괜찮을 것입니다. 구조에 대한 포인터 전달에 대한 유효한 포인트. 이것은 빠른 예였습니다. 그래서 나는 이것을 이렇게 썼다. –

+1

@ KingkongJnr 모든 값이 16 비트에 맞을만큼 작다는 것을 안다면 괜찮을 것입니다. 32 비트에서 16 비트로 지정하면 상위 비트가 무시됩니다. – Barmar

+1

간단한 할당은 암시 적으로 캐스트와 똑같은 변환을 수행합니다. 정수를 부호없는 유형으로 변환하는 것은 잘 정의되어 있습니다. 상위 비트를 버립니다. –

0

깨끗합니다. 오래된 컴파일러는 캐스트없이 이것을 받아 들일 것입니다. uint32 값의 하위 16 비트 만 전달한다는 점을 명심하십시오.