Есть ли причина объявлять что-то volatile const в C, но только volatile в C++?

Я использовал файл заголовка в своем проекте, который имел следующие определения:

#ifdef __cplusplus
  extern "C" {
#endif 

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

__I используется в другом заголовочном файле следующим образом:

    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 должно быть сделано const в C, но не в C++? Вы все еще можете изменить значение, на которое указывает CR, поскольку у вас есть адрес, но мне просто любопытно, почему определение __I отличается.

Для всех, кто интересуется, для чего это или из чего, определения __I взяты из IAR Embedded Workbench ARM для Cortex-M4, а структура — из файлов CMSIS LM4F120H5QR Texas Instruments.


person SoftwareDev    schedule 19.10.2014    source источник
comment
В C++ const обеспечивает внутреннюю связь. Я не знаю, работает ли это в C, но подозреваю, что нет. В любом случае, обратите внимание, что __I — это имя, зарезервированное для реализации, и его не следует использовать в пользовательском коде.   -  person Cheers and hth. - Alf    schedule 20.10.2014
comment
@Mat McNabb Я имел в виду, что, поскольку у меня есть точный адрес регистра CR, я могу сделать следующее #define GPIO_PORTF_CR_R (*((volatile unsigned long *)0x40025524)) , затем выполнить GPIO_PORTF_CR_R = xxxxx , и это изменяет значение регистра.   -  person SoftwareDev    schedule 20.10.2014
comment
@SoftwareDev OK - volatile const CR означает, что вы не можете использовать CR для изменения регистра; конечно, это можно изменить другими способами   -  person M.M    schedule 20.10.2014
comment
@MattMcNabb Да, я думал, что вы это имели в виду, просто хотел добавить это для разъяснения другим. Спасибо.   -  person SoftwareDev    schedule 20.10.2014


Ответы (1)


В C++ переменные const в области файла по умолчанию имеют статическую связь, что нежелательно для GPIO с отображением памяти. «Правильным» решением для этого является ключевое слово extern, но здесь его нельзя использовать, так как очевидно, что __I также должно работать с членами класса. Таким образом, удаление const делает связь по умолчанию extern по желанию.

person Ben Voigt    schedule 19.10.2014
comment
Если это причина, я бы также отметил, что тот, кто написал исходный код, вероятно, должен был разветвить __I, чтобы иметь другую версию для переменных-членов, чем для глобальных. - person M.M; 20.10.2014
comment
@MattMcNabb: задним числом всегда 20-20. Поддержка C++, вероятно, была добавлена ​​задолго до того, как макрос был использован в коде C как для глобальных переменных, так и для членов. - person Ben Voigt; 20.10.2014
comment
@BenVoigt Имеет смысл. В общем, человек, который написал этот код, сказал, что нет способа сделать CR только для чтения в C++, хотя это то, что мы хотим? Хотя я больше склоняюсь к тому, что человек, который написал код C, неправильно читает таблицу данных, потому что, согласно ему, значение регистра CR может быть изменено по умолчанию, на самом деле, если его нельзя изменить, нет возможности включить подтягивание резистор в одном из переключателей на макетной плате, которую я использую. - person SoftwareDev; 20.10.2014
comment
@SoftwareDev: я не смотрел конкретный регистр для конкретного чипа или даже семейства LM4F. Но я предполагаю, что эти макросы используются для всех регистров специальных функций, а не только для GPIO CR? Может быть ошибкой то, что CR помечен в заголовке только для ввода, но, безусловно, есть довольно много регистров, которые действительно должны быть только для ввода. - person Ben Voigt; 20.10.2014
comment
@SoftwareDev: На самом деле заголовочный файл может быть намеренно более строгим, чем аппаратное обеспечение. Вы пишете GPIOCR только в том случае, если собираетесь отключить функцию программирования выводов программирования... это путь в один конец, если у вас есть ошибка. - person Ben Voigt; 20.10.2014