Visibility of identifiers

Inno Setup Preprocessor

Visibility of identifiers

Variable (as well as macro) declarations can be defined as "public," "protected," or "private." To define a specifically public, protected, or private variable, its name in define directive should be prepended with one of the keywords (visibility resolution clauses):

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

Hereinafter in this topic, "variables" also refers to macros as well.

Public variables are ordinary variables as they used to be in previous versions of ISPP. They are accessible (unless any protected or private identifiers override them, see below) from anywhere after the point they are declared.

Protected variables are accessible only in the file they are declared in (declaration file) and in files included by declaration file via include or file directives. They can be said (with some reserves) that they are public variables which are automatically undefined once the declaration 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 explicity 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, therefore, as in any programming language 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.

#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 explicity specifying its visibility. When default visibility is not set, public is assumed by default. Note, that setting default visibility is not propagated on included or parent files.

In macro expressions, avoid using identifiers of lower visibility than the one macro is declared in. This may cause "Undeclared identifier" errors if macro 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 parent file doesn't, declare it as protected. Declare it as public otherwise. If you're unsure, then protected visibility is the common case.