Можно ли использовать макрос для доступа к переменной только для чтения?
-
02-07-2019 - |
Вопрос
Можете ли вы определить макрос, который обращается к обычной переменной, но только для чтения (кроме определения ее как вызова функции)?Например, можно ли определить макрос VALUE в следующем коде таким образом, чтобы функция dostuff() вызывала ошибку компиляции?
struct myobj {
int value;
}
/* This macro does not satisfy the read-only requirement */
#define VALUE(o) (o)->value
/* This macro uses a function, unfortunately */
int getvalue(struct myobj *o) { return o->value; }
#define VALUE(o) getvalue(o)
void dostuff(struct myobj *foo) {
printf("The value of foo is %d.\n", VALUE(foo)); /* OK */
VALUE(foo) = 1; /* We want a compile error here */
foo->value = 1; /* This is ok. */
}
Решение
Если переменная всегда числовая, это работает:
#define VALUE(x) (x+0)
или в контексте вашего примера,
#define VALUE(x) (x->value+0)
Другие советы
Хорошо, я придумал один:
#define VALUE(o) (1 ? (o)->value : 0)
См. §6.5.17 стандарта C (C99 и C1x):«Оператор-запятая не дает l-значения».
#define VALUE(x) (0, x)
(Непереносимо на C++.)
Пытаться
#define VALUE(o) (const int)((o)->value)
Это головоломка или инженерная задача?Если это инженерная задача, то есть более эффективные способы добиться непрозрачности структур в C.В эта статья в блоге, я написал достаточно приличное описание того, как это сделать на C.
Не связан с StackOverflow