2014-10-19 11 views
8

했다 그 다음의 정의 (들) :C에서 "volatile const"를 선언 할 이유가 있습니까? C++에서 "volatile"만 선언 할 이유가 있습니까? 내 프로젝트에 헤더 파일을 사용하고 있었다

다른 헤더 파일에 다음과 같이 __I 사용
#ifdef __cplusplus 
    extern "C" { 
#endif 

#ifdef __cplusplus 
    #define __I  volatile    /*!< Defines 'read only' permissions*/ 
#else 
    #define __I  volatile const  /*!< Defines 'read only' permissions*/ 
#endif 

:

typedef struct { 
    // more members before   
     __I uint32_t CR; /*!< GPIO Commit*/ 
    // more members after 

    } GPIOA_Type; 

#define GPIOF_BASE      0x40025000UL 
#define GPIOF       ((GPIOA_Type *) GPIOF_BASE) 

내 질문은 왜이다 __I은 C에서는 const가되지만 C++에서는 const가되지 않습니까? 주소가 있기 때문에 CR이 가리키는 값을 수정할 수는 있지만, 왜 __I의 정의가 다른지 골반입니다. 이 또는에서 무엇 관심이 사람을 위해

__I 정의는 IAR 임베디드 워크 벤치 ARM의 코어 텍스 M4 에 대해, 그리고 구조체는 Texas Instruments LM4F120H5QR CMSIS 파일에서입니다.

+1

C++에서 'const'는 내부 연결을 제공합니다. 나는 그것이 C 언어로되어 있는지는 모르지만, 나는 그렇지 않다고 생각합니다. 어쨌든'__I'는 구현에 예약 된 이름이므로 사용자 코드에 사용하면 안됩니다. –

+0

@Mat McNabb 나는 CR 레지스터가 정확한 주소를 가지고 있기 때문에 GPIO_PORTF_CR_R (* (volatile unsigned long *) 0x40025524)를 정의 할 수있다. GPIO_PORTF_CR_R = xxxxx를 실행하면 레지스터 값이 변경된다. . – SoftwareDev

+0

@ SoftwareDev OK - '휘발성 const CR'은 'CR'을 사용하여 레지스터를 수정할 수 없음을 의미합니다. 물론 다른 방법으로 수정 될 수 있습니다. –

답변

7

C++에서 파일 범위의 변수는 기본적으로 정적 링크이며, 메모리 매핑 된 GPIO에는 적합하지 않습니다. 그것에 대한 "올바른"픽은 extern 키워드이지만 여기서는 사용할 수 없습니다. __I도 클래스 멤버와 함께 작업해야하는 것이 분명하기 때문입니다. 따라서 const을 제거하면 원하는대로 기본 연결 extern이됩니다.

+0

이것이 이유라면 원래 코드를 작성한 사람은 전역 변수보다 멤버 변수에 대해 다른 버전을 사용하도록 "forked"해야 할 것입니다. –

+0

@MattMcNabb : Hindsight는 항상 20-20입니다. 매크로가 C 코드에서 전역 변수와 멤버 둘 다에 사용 된 후에는 C++ 지원이 추가 된 것으로 보입니다. –

+0

@BenVoigt 의미가 있습니다. 그래서 기본적으로이 코드를 작성한 사람은 "CR을 C++로만 읽을 수있는 방법이 없다"고 말했다. CR 레지스터의 값을 기본값에서 변경할 수 있기 때문에 데이터 시트를 올바르게 읽지 않는 C 코드를 작성한 사람에게 더 기대고 있지만 실제로 변경할 수 없다면 풀업을 사용할 수있는 방법이 없습니다 저항 보드의 스위치 중 하나를 사용하고 있습니다. – SoftwareDev