Next: , Previous: , Up: MFL   [Contents][Index]


4.18 Variable and Constant Shadowing

When any two named entities happen to have the same name we say that a name clash occurs. The handling of name clashes depends on types of the entities involved in it.

function – any

A name of a constant or variable can coincide with that of a function, it does not produce any warnings or errors because functions, variables and constants use different namespaces. For example, the following code is correct:

const a 4

func a()
do
  echo a
done

When executed, it prints ‘4’.

function – function, handler – function, and function – handler

Redefinition of a function or using a predefined handler name (see Handlers) as a function name results in a fatal error. For example, compiling this code:

func a()
do
  echo "1"
done

func a()
do
  echo "2"
done

causes the following error message:

mailfromd: sample.mfl:9: syntax error, unexpected
FUNCTION_PROC, expecting IDENTIFIER

handler – variable

A variable name can coincide with a handler name. For example, the following code is perfectly OK:

string envfrom "M"
prog envfrom
do
        echo envfrom
done

handler – handler

If two handlers with the same name are defined, the definition that appears further in the source text replaces the previous one. A warning message is issued, indicating locations of both definitions, e.g.:

mailfromd: sample.mfl:116: Warning: Redefinition of handler
`envfrom'
mailfromd: sample.mfl:34: Warning: This is the location of the
previous definition

variable – variable

Defining a variable having the same name as an already defined one results in a warning message being displayed. The compilation succeeds. The second variable shadows the first, that is any subsequent references to the variable name will refer to the second variable. For example:

string x "Text"
number x 1

prog envfrom
do
  echo x
done

Compiling this code results in the following diagnostics:

mailfromd: sample.mfl:4: Redeclaring `x' as different data type
mailfromd: sample.mfl:2: This is the location of the previous
definition

Executing it prints ‘1’, i.e. the value of the last definition of x.

The scope of the shadowing depends on storage classes of the two variables. If both of them have external storage class (i.e. are global ones), the shadowing remains in effect until the end of input. In other words, the previous definition of the variable is effectively forgotten.

If the previous definition is a global, and the shadowing definition is an automatic variable or a function parameter, the scope of this shadowing ends with the scope of the second variable, after which the previous definition (global) becomes visible again. Consider the following code:

set x "initial"

func foo(string x) returns string
do
  return x
done

prog envfrom
do
  echo foo("param")
  echo x
done

Its compilation produces the following warning:

mailfromd: sample.mfl:3: Warning: Parameter `x' is shadowing a global

When executed, it produces the following output:

param
initial
State envfrom: continue

variable – constant

If a constant is defined which has the same name as a previously defined variable (the constant shadows the variable), the compiler prints the following diagnostic message:

file:line: Warning: Constant name `name' clashes with a variable name
file:line: Warning: This is the location of the previous definition

A similar diagnostics is issued if a variable is defined whose name coincides with a previously defined constant (the variable shadows the constant).

In any case, any subsequent notation %name refers to the last defined symbol, be it variable or constant.

Notice, that shadowing occurs only when using %name notation. Referring to the constant using its name without ‘%’ allows to avoid shadowing effects.

If a variable shadows a constant, the scope of the shadowing depends on the storage class of the variable. For automatic variables and function parameters, it ends with the final done closing the function. For global variables, it lasts up to the end of input.

For example, consider the following code:

const a 4

func foo(string a)
do
  echo a
done

prog envfrom
do
  foo(10)
  echo a
done

When run, it produces the following output:

$ mailfromd --test sample.mfl
mailfromd: sample.mfl:3: Warning: Variable name `a' clashes with a
constant name
mailfromd: sample.mfl:1: Warning: This is the location of the previous
definition
10
4
State envfrom: continue

constant – constant

Redefining a constant produces a warning message. The latter definition shadows the former. Shadowing remains in effect until the end of input.


Next: , Previous: , Up: MFL   [Contents][Index]