2016-09-08 6 views
1

고려하십시오. 32 비트의 부호없는 두 개의 숫자가 하나의 배열에 저장되어 있습니다. 첫 번째 숫자는 위치 [0; 3]이고 두 번째는 [4; 8]. 이제 숫자 중 하나의 값을 변경하려면 다음 코드가 허용/문제가 있습니까?uint32_t *를 사용하여 uint8_t 배열의 값을 변경하십시오.

uint8_t array[8]; 
//...Fill it up... 

uint32_t *ptr = NULL; 
ptr = (uint32_t*)&array[0]; 
*ptr = 12345; 

ptr = (uint32_t*)&array[4]; 
*ptr = 54321; 
+5

예, 그것은 문제가 , http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule –

+2

유효 유형 (일명 엄격한 앨리어싱) 규칙을 위반했습니다.이 규칙은 분명하지 않습니다 **! 마샬링 사용 – Olaf

+1

다른 방법으로도 할 수 있습니다 :'uint32_t' 값으로 채우는'uint32_t'의 배열을 가지고 있습니다. 그러면'uint8_t *'(" 네가 걱정하지 않는다면 데이터 표현). –

답변

1

당신은 uint32_t에 대한 포인터와 함께 uint8_t 배열에 액세스 할 수 있습니다. the strict aliasing rule의 위반입니다 (다른 방법은 괜찮습니다. uint8_t이 문자 유형 인 경우).

대신 (위 C99 등) C 시스템에 입력을 회피하기 위해 "type punning"을 사용할 수 있습니다이를 위해, 당신은 각각의 유형의 구성원으로 union을 사용합니다.

union TypePunning { 
    uint32_t the_ints[2]; 
    uint8_t the_bytes[2 * sizeof(uint32_t)]; 
} 
// now e.g. write to the_bytes[1] and see the effect in the_ints[0]. 
// Beware of system endianness, though! 
+0

'uint8_t'는 절대로 문자 유형이 아닙니다! 항상 부호없는 정수 유형입니다. 그리고 ok not의 다른 길. 6.5p6, 첫 번째 문장을보십시오! 그리고 UB를 부르지 않는 반면, 노동 조합 접근법 역시 그 문제를 가지고 있습니다. – Olaf

+0

@Olaf,'uint8_t'는 정수형이고'char'는 그렇지 않습니다. 이 표준에는 더 넓은 범주의 "문자 유형"이 없습니다. 특히'signed char'와'unsigned char'는'char'와 같이 그룹화되지 않습니다. 부호가 있거나 부호없는 유형은 정수 유형으로 그룹화됩니다. –

+0

@JohnBollinger : 6.2.5p6, 마지막 문장 : "... 표준 및 확장 된 부호없는 정수 유형을 통칭하여 _unsigned 정수 유형 _이라고합니다." 'uint8_t'는 _standard unsigned integer type_ 인'unsigned char' 이외의 다른 것일 수 없습니다. – Olaf

관련 문제