#c #scope
#c #область видимости
Вопрос:
Есть ли способ отключить весь доступ к переменной в определенной области видимости?
Ее использование может быть похоже на это :-
int outerOnly=5; //primitive or class or struct, it can also be a field
outerOnly=4; //ok
{//vvv The disable command may be in a block?
disable outerOnly; //<--- I want some thing like this.
outerOnly=4; //should compile error (may be assert fail?)
int c=outerOnly; //should compile error
}
outerOnly=4; //ok
Если ответ отрицательный, есть ли какая-либо функция, наиболее близкая к этой?
Это было бы полезно в нескольких ситуациях отладки.
Редактировать: Например, я точно знаю, что определенная область видимости (также слишком уникальная, чтобы быть функцией) никогда не должна обращаться к одной определенной переменной.
Комментарии:
1. Нет, вы не можете сделать ничего подобного, и я не уверен, что есть что-то подобное. На самом деле не вижу никакой помощи в отладке, поскольку точки останова и ведение журнала, вероятно, уже дали бы необходимую информацию
2. Самое близкое, что вы можете сделать, это переместить этот внутренний блок в его собственную функцию (хотя глобальные значения все еще доступны).
3. «Это было бы полезно в нескольких ситуациях отладки». — Я так не думаю.
4. «Например, я точно знаю, что определенная область видимости (также слишком уникальная, чтобы быть функцией) никогда не должна обращаться к одной определенной переменной». — Если ваш код настолько сложен, что вы считаете, что такой ужасный взлом был бы полезен, то, пожалуйста, реорганизуйте свой код таким образом, чтобы переменные случайно не появлялись в неправильных областях, не вызывая ошибок компиляции. И что именно «слишком уникально, чтобы быть функцией»?
5. @Christian Hackl «слишком уникально, чтобы быть функцией» = Если она станет функцией, она будет вызвана только 1 раз. Этой функции также может потребоваться доступ к некоторым локальным переменным вызывающего объекта, поэтому мне придется передать их вручную. Таким образом, ИМХО, я думаю, что не совсем уместно делать это функцией.
Ответ №1:
Рассмотрите возможность реализации чего-то подобного (возможно, с удаленными конструкторами копирования и операторами присваивания):
struct disable
{
private:
disable(const disableamp;) = delete;
disableamp; operator=(const disableamp;) = delete;
public:
disable() {}
};
Затем, поместив
disable outerOnly;
внутри внутренней области видимости это привело бы в значительной степени к желаемым ошибкам.
Однако имейте в виду, как прокомментировал @Cornstalks, что это может привести к предупреждениям компилятора, связанным с затенением (которые, в свою очередь, обычно могут быть отключены в каждом конкретном случае).
Комментарии:
1. Обратите внимание, что это может вызвать предупреждения с определениями теней, в зависимости от настроек вашего компилятора.
2. Спасибо AlexD. 1 Возможно ли также избежать предупреждения (упомянутого Cornstalks) от компилятора?
3. Я бы порекомендовал макрос для небольшой условной компиляции.
#define DISABLE(var) disable var;
По крайней мере, разрешит сборку без предупреждений при правильном-D
выборе.4. Что такое «обычно может быть отключено в каждом конкретном случае»? Вы имеете в виду — построчно? Как? Я новичок в C .
5. @javaLover У вас может быть макрос, который (1) сохранит настройки; (2) отключит конкретное предупреждение; (3) выполнит
disable(var)
; (4) вернет настройки обратно. Таким образом, вам не нужно полностью отключать предупреждение, которое может быть полезно в других случаях. Посмотрите на#pragma
s для вашего компилятора.
Ответ №2:
Есть ли способ отключить весь доступ к переменной в определенной области видимости?
Нет, такой функции нет.
Если ответ отрицательный, есть ли какая-либо функция, наиболее близкая к этой?
Вместо простого блока вы могли бы определить и вызвать замыкание, которое не фиксирует нежелательную переменную:
int outerOnly;
int innerToo;
[amp;innerToo]()
{
innerToo = 42; // ok
outerOnly = 4; // fails to compile
int c = outerOnly; // fails to compile
}();
Ответ №3:
Просто сделайте struct Outeronly;
.
Обратите внимание, что сообщения об ошибках могут вызвать недоумение у тех, кто с ними не знаком.
Ответ №4:
Вот довольно простое решение:
int main()
{
int outerOnly=5; //primitive or class or struct, it can also be a field
outerOnly=4; //ok
#define outerOnly outerOnly_disabled
//outerOnly=4; //error outerOnly_disabled is not declared
//int c=outerOnly; //error
#undef outerOnly
outerOnly=4; //ok
}