2016-12-15 8 views
1

코드 :이렇게 포인터를 캐스팅 할 수 있습니까?

unsigned char array_add[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 

... 

if ((*((uint32_t*)array_add)!=0)||(*((uint32_t*)array_add+1)!=0)) 
{ 
... 
} 

나는 배열이 모두 0인지 확인하고 싶습니다. 그래서 당연히 저는 unsigned int 32 타입에 대한 첫 번째 멤버의 주소이기도 한 배열의 주소를 캐스팅하려고 생각했습니다. 따라서이 코드는 64 비트, 8 바이트이기 때문에 두 번만하면됩니다. 정렬. 문제는 성공적으로 컴파일되었지만 프로그램이 여기에서 항상 충돌합니다.

저는 8 비트 마이크로 컨트롤러 인 cortex-M0에서 프로그램을 실행하고 있습니다.

내가 얼마나 잘못 되었나요?

+1

이러한 코드 작성을 중단하십시오! 그것은 문제를 요구하는 것처럼 보입니다. 캐스트가 정의되지 않은 동작을 호출하는 것을 고려하십시오. 왜 당신은'uint32_t [2]를 사용하지 않습니까? – Olaf

+1

그리고 Cortex-M0는 8 비트 CPU가 아닙니다! – Olaf

+0

포인터를 사용하지 않는 이유는 무엇입니까? unsigned char * pt = array_add; if ((* (pt)! = 0) || (* (pt + 1)! = 0)) – dante

답변

-3

나는 확실하지 않다하지만 배열은 8 바이트가있는 경우 다음 단지 long long 변수에 기본 주소를 할당하고 배열이 모두 0

편집 한 경우 확인의 문제를 해결해야한다고 0 비교 : Olaf의 코멘트 후 나는 long longint64_t으로 대체한다고 말할 것입니다. 그러나 배열을 반복하고 검사하기위한 간단한 루프가 필요한 이유는 무엇입니까? 8 개의 문자 만 있으면 비교할 수 있습니다.

편집 2 : 다른 방법은 OR의 모든 요소를 ​​OR 한 다음 0과 비교하는 것입니다. 모두 0 인 경우 OR은 0입니다. 나는 CMP가 빠르거나 빠를지를 모른다. 정확한 CPU 사이클 요구 사항에 대해서는 Cortex-M0 문서를 참조하십시오. 그러나 CMP 속도가 느려질 것으로 예상됩니다.

+0

'long long'은 64 비트를 보장하지 않습니다! 테는 OP가 고정 폭 타입을 사용하는 것이 맞습니다. – Olaf

+0

페이지 번호 28 of n1570.pdf는 long long이 64 비트를 요구하는 최소 범위를 가지고 있다고 말합니다. 'long long'은 64 비트가 보장되지 않는다고 말하는 곳에 전화 해주세요. 사양에 뭔가 다른 것을 놓쳤습니까? – user902384

+2

당신은 이미 관련 부분을 인용했습니다! 그것을 다시주의 깊게 읽으십시오! – Olaf

2

이론상 이것은 작동 할 수 있지만 실제로는 정렬되지 않은 메모리 액세스가 고려됩니다. uint32_t는 다음 uint32_t* 1 개 바이트 정렬 요건을 갖는다 unsigned char 배열 캐스팅 (4 바이트 등)로 정렬 된 메모리 액세스를 요구하는 경우

uint32_t의 정렬되지 않은 배열에 대한 포인터를 생성한다. documentation 따르면

:

텍스 M0 프로세서에 정렬되지 않은 액세스를 지원하지 않습니다

. 정렬되지 않은 메모리 액세스 작업을 수행하려고하면 HardFault 예외가 발생합니다.

실제로 이것은 특정 상황에서 정의되지 않은 동작을 유발하는 위험하고 깨지기 쉬운 코드입니다 (Olaf가 지적한 바, here).

+1

코드는 또한 유효 유형 규칙을 위반하므로 UB를 호출합니다 (이 중 정렬은 ** 하나 ** 문제이며 다른 것은 컴파일러 최적화를 포함합니다). – Olaf

1

한 번에 여러 바이트를 테스트하려면 memcmp()을 사용할 수 있습니다.

속도가 얼마나 빠른지는 최적화 컴파일러가 컴파일러에 따라 더 많은 영향을 미칩니다. 한 번에 빠른 8 바이트 (또는 2 개의 4 바이트) 비교를 수행하는 코드를 간단하게 내보낼 수 있습니다. 심지어 memcmp()은 8 비트 프로세서에서 너무 느리지 않을 수 있습니다. 프로파일 링 코드가 도움이됩니다.

마이크로 최적화에서 중요한 최적화를 위해 코더의 시간을 너무 자주 사용하지 않으므로주의하십시오.

unsigned char array_add[8] = ... 
const unsigned char array_zero[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
if (memcmp(array_zero, array_add, 8) == 0) ... 

또 다른 방법은 union 이용한다. add.arr8[0]이 최하위 또는 최하위 바이트인지 가정하지 않도록주의하십시오.일반적으로

union { 
    uint8_t array8[8]; 
    uint64_t array64; 
} add; 

// below code will check all 8 of the add.array8[] is they are zero. 
if (add.array64 == 0) 

매우 선택의 경우에 명확한 코드와 예비 소형 최적화를 쓰기에 초점을 맞 춥니 다.