2014-11-05 7 views
9
내가 쓰고 같이, 메모리 맵에서 레지스터를 읽고 있습니다

에 사용되는 '무효 *'유형의 포인터 :경고 : 산술

warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith] 
: 컴파일러는 나에게 이런 경고를 제공

//READ 
return *((volatile uint32_t *) (map + offset)); 

//WRITE 
*((volatile uint32_t *) (map + offset)) = value; 

그러나

코드를 변경하여 경고를 제거하려면 어떻게해야합니까? 나는 C++과 리눅스를 사용하고있다.

+3

* char *로 캐스팅하십시오. * byte * offset을 원한다고 가정하십시오. 너? –

+0

맞습니다 맵은 void *입니다, 감사합니다. – user1876942

+0

'map'을 크기 1의 타입에 대한 포인터에 캐스트해야합니다. 표준에 의해 크기가 1로 보장 된 유일한 타입은'char'이므로,'char *'로 캐스팅해야합니다. –

답변

6

유형 공백은 불완전 유형입니다. 그 크기는 알려져 있지 않습니다. 따라서 void에 대한 포인터를 사용한 포인터 산술은 의미가 없습니다. void를 가리키는 포인터를 char에 대한 포인터와 같은 다른 유형의 포인터로 캐스트해야합니다. 또한 한정자 volatile로 선언 된 객체를 할당 할 수 없다는 점을 고려하십시오.

15

void*은 알 수없는 유형의 포인터이므로 컴파일러는 포인터 연산이 불가능하므로 포인터가 계산할 수 없습니다.

가장 좋은 방법은 map을 바이트 너비 형식으로 캐스팅 한 다음 산술 연산을 수행하는 것입니다. 이 경우 uint8_t을 사용할 수 있습니다.

//READ 
return *((volatile uint32_t *) (((uint8_t*)map) + offset)); 

//WRITE 
*((volatile uint32_t *) (((uint8_t*)map)+ offset)) = value; 
+0

하지만 void *는 잘 알려진 유형이며, 주소 유형입니다. 주소 유형을 가리킬 수 있습니다 ... 해결책은 정적 인 것 같아요. uintptr_t *, 그 다음에 – Dmitry

+1

그것은 char에 캐스트하는 것이 더 관용적입니다. '로, sizeof (char)는 1로 정의된다. – Artyer