Variables (as well as user defined functions, read "variable or user defined function" anywhere it says "variable" below) can be explicitly defined as "public," "protected," or "private." To define such a variable, its name in its define directive should be prepended with one of the visibility keywords:
#define public MyVar 12
#define protected MyVar 13
#define private MyVar 14
In the example above, none of the last two declarations undefine any of the previous, though they share the same identifier (MyVar). This is because they are declared in different visibilities.
Public variables are ordinary variables accessible from anywhere after the point they are declared.
Protected variables are accessible only in the file they are declared in and in files included by that file via include or file directives. You can basically think of them as public variables which are automatically undefined once their file has finished.
Private variables are accessible only in the file they are declared in. They are not propagated to any other file, be it included or "parent" file.
Since ISPP does not have semantics of pushing and popping variable value, visibility resolution can be useful.
Note that you cannot explicitly refer to a variable in a specific visibility from expressions. Given the example above, if MyVar is mentioned in expression in declaration file, its identifier refers to private MyVar. If it is mentioned in included file, it refers to protected MyVar. If it is mentioned in one of the files above the declaration file on the include stack (i. e. one of the files from which a chain of include directives resulted in processing the declaration file), it refers to public MyVar.
Also note, that if we'd swap last two declarations from the above example, private MyVar would become inaccessible (until protected is undefined) because protected would be declared after it and would take precedence. But it wouldn't undefine its private counterpart.
Each file can set a default visibility, the visibility that will be used when no resolution clause is specified in variable declaration. This can be done using define directive, for example:
#define protected
sets protected visibility by default.
The default visibility isn't used when evaluating expressions, it is only used when a variable is defined or undefined without explicitly specifying its visibility. When default visibility is not set, public is assumed by default. Setting default visibility is not propagated on included or parent files.
In user defined function expressions, avoid using identifiers of lower visibility than the one the user defined function is declared in. This may cause "Undeclared identifier" errors if the user defined function is called from another file.
It is recommended that you use appropriate visibility when declaring variables to avoid problems with unexpected redefinition of a variable (for example in included third-party file). If no included files depend on a variable, declare it as private. If they do, but the parent file doesn't, declare it as protected. Declare it as public otherwise. If you're unsure, then protected visibility is the common case.