возможно ли сделать переменную недоступной в определенной области видимости?

#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
}