Предоставляет ли C возможность объявить внешнюю переменную как «только для чтения», но определить ее как записываемую?

Я разрабатываю библиотеку абстракции оборудования для встроенного продукта с использованием GCC C. В библиотеке есть переменная, которая должна быть доступна только для чтения для приложения, которое связывает библиотеку, но может быть изменено из единицы компиляции, которая ее определяет.

Существует стандартный приемлемый способ объявления целого (в заголовочном файле библиотеки), который позволит приложению считывать значение в переменной, но сообщать компилятору о возникновении ошибки, если предпринимаются какие-либо попытки генерировать код, который записывает обратно к нему? Например, если я должен объявить функцию как:

extern void foo(int const bar); 

… тогда вызывающему абоненту разрешено передавать локальную переменную:

 int bar = 0; foo(bar); 

… но если объявление функции пытается записать в bar :

 void foo(int const bar) { bar = 99; } 

… тогда компилятор своевременно сообщает об ошибке: назначение «bar» только для чтения.

Синтаксис размещения const перед именем не относится к переменным таким же образом, как и к параметрам функции, и две приведенные ниже строки кажутся фактически эквивалентными:

 extern const int x; extern int const y; 

… потому что определение y как int y; приводит к ошибке: конфликтующие classификаторы типов для «y», как я ожидал бы, если бы x был определен как int x; ,

Я знаю, что я могу обойти проблему, объявив и определяя функцию доступа, которая возвращает значение (которое может использоваться только как r-значение).

Здесь я прочитал ряд связанных вопросов, но ни один из них не нашел окончательного ответа для C (в отличие от C ++ или C #):

C – Доступ к объявлению const без константы

Смешивание внешнего и const

Пожалуйста, кто-нибудь может указать мне пример того, как я могу это достичь, или подтвердить мое подозрение, что оно не является синтаксически достижимым?

Внутри библиотеки есть переменная, которая должна быть доступна только для чтения для приложения, которое связывает библиотеку, но может быть изменено из единицы компиляции, которая ее определяет.

Решение заключается в использовании объектно-ориентированного дизайна, а именно в том, что называется частной инкапсуляцией .

module.h

 int module_get_x (void); 

module.c

 static int x; int module_get_x (void) { return x; } 

main.c

 #include "module.h" int main(void) { int value = module_get_x(); } 

Если переменная должна быть прочитана-записана внутри модуля, то это единственный правильный способ сделать это. Все остальные способы – это всего лишь некоторый вкус программирования спагетти.

Вы можете использовать указатель, чтобы преодолеть проблему.

module.c

 static int readwrite = 0; int const * const readonly = &readwrite; 

module.h

 extern int const * const readonly; 

Если нет причин выставлять адрес переменной, вы должны предпочесть подход Lundins getter к правильной инкапсуляции.