Limiting Variable Scope

In C, how do I restrict the scope of a global variable to the file in which it's declared?

You #included bar.c, which has the effect of causing the preprocessor to literally copy the contents of bar.c into foo.c before the compiler touches it.

Try getting rid of the include, but telling your compiler to compile both files (e.g. gcc foo.c bar.c) and watch it complain as you expect.

Edit: I suppose the primary confusion is between the compiler and the preprocessor. Language rules are enforced by the compiler. The preprocessor runs before the compiler, and acts on those commands prefixed by #. All the preprocessor does is manipulate plain text. It doesn't parse the code or try to interpret the meaning of the code in any way. The "#include" directive is very literal - it tells the preprocessor "insert the contents of this file here". This is why you normally only use #include on .h (header) files, and you only place function prototypes and extern variable declarations in header files. Otherwise, you will end up compiling the same functions, or defining the same variables, multiple times, which is not legal.

How to limit scope of variable needed to construct object that lives longer?

You could use a lambda:

Object obj{[&]{ ObjectDef def{importantData}; def.setOptionalData(100); return def; }()};

If ObjectDef frequently needs it's optional data set and this is a common pattern, consider adding a constructor to ObjectDef that allows optional data to be set or creating a named helper function that does the job the lambda does here.

How can I limit readonly variable scope to a function?

Replace:

readonly local foo="bar"

with:

local -r foo="bar"

The issue is that readonly local foo="bar" defines two readonly variables: one named local and one namedfoo. It does not create any local variables.

By contrast, local -r foo="bar" creates a variable named foo which is both local and readonly.

As David C Rankin points out, once you have created a global read-only variable, you cannot unset it. You need to close your existing shell and start a new one.

Java: Strategy for limiting scope of a variable

Another solution specific to your sample code : you can declare variables in a for loop's initialization statement which will only be accessible in the loop's body.

for (String line=br.readLine(); line != null ; line = br.readLine()) {
//line is accessible
}
// line is undeclared

Every while loop can be converted to a for loop, but the resulting loop might often be confusing, so comment profusely.

Limit Python function scope to local variables only

I feel like I should preface this with: Do not actually do this.

You (sort of) can with functions, but you will also disable calls to all other global methods and variables, which I do not imagine you would like to do.

You can use the following decorator to have the function act like there are no variables in the global namespace:

import types
noglobal = lambda f: types.FunctionType(f.__code__, {})

And then call your function:

a = 1
@noglobal
def my_fun(x):
print(x)
print(a)
my_fun(2)

However this actually results in a different error than you want, it results in:

NameError: name 'print' is not defined

By not allowing globals to be used, you cannot use print() either.

Now, you could pass in the functions that you want to use as parameters, which would allow you to use them inside the function, but this is not a good approach and it is much better to just keep your globals clean.

a = 1
@noglobal
def my_fun(x, p):
p(x)
p(a)
my_fun(2, print)

Output:

2
NameError: name 'a' is not defined

Does bc not limit a variable's scope?

You need to specify an AUTO_LIST in your function definition. From the bc manual,

`define' NAME `(' PARAMETERS `)' `{' NEWLINE
AUTO_LIST STATEMENT_LIST `}'

[...]

The AUTO_LIST is an optional list of variables that are for "local"
use. The syntax of the auto list (if present) is "`auto' NAME, ... ;".
(The semicolon is optional.) Each NAME is the name of an auto
variable. Arrays may be specified by using the same notation as used
in parameters. These variables have their values pushed onto a stack
at the start of the function. The variables are then initialized to
zero and used throughout the execution of the function. At function
exit, these variables are popped so that the original value (at the
time of the function call) of these variables are restored. The
parameters are really auto variables that are initialized to a value
provided in the function call. Auto variables are different than
traditional local variables because if function A calls function B, B
may access function A's auto variables by just using the same name,
unless function B has called them auto variables. Due to the fact that
auto variables and parameters are pushed onto a stack, `bc' supports
recursive functions.

So to keep the test variable "local" in your function, you'd use

define void f () { auto test; test=42; print "all done\n"; }

static - used only for limiting scope?

The static keyword serves two distinct purposes in C, what I call duration (the lifetime of an object) and visibility (where you can use an object from). Keep in mind the C standard actually uses different words for these two concepts but I've found in teaching the language that it's best to use everyday terms to begin with.

When used at file level (outside of any function), it controls visibility. The duration of variables defined at file level are already defined as being the entire duration of the program so you don't need static for that.

Static variables at file level are invisible to anything outside the translation unit (the linker can't see it).

When used at function level (inside a function), it controls duration. That's because the visibility is already defined as being local to that function.

In that case, the duration of the variable is the entire duration of the program and the value is maintained between invocations of the function.



Related Topics



Leave a reply



Submit