Loading src/16-declaring-dynamic-behaviour.md +436 −84 Original line number Diff line number Diff line Loading @@ -180,126 +180,478 @@ control { ### Actual parameters An _actual parameter list_ supplies parameters to an invocation or instantiation of a parameterized TTCN-3 language element. An _actual parameter list_ may be written using _list notation_, _assignment notation_, or _mixed notation_. - empty parameter list may be omitted for parameterized object that are not functions, testcase, altstep, external functions - notations - list notation - assignment notation (evaluated in order of actual arguments) - midex notation - passing an parameter to a formal parameter is semantically equivalent to an assignment. - this implies that value expansion is (left-hand side reference semantics) - 5.4.2.m aliasing (of structs and unions) in the same function is forbidden (can we actually enforce that?) - actual parameters are mapped on the - evaluated in the order they are passed - evaluated in the scope of the caller _- assignment list notation - special rules altsteps, templates - parameter kind: - in (default): - by value (copy, type compatibility) - optional default value (referencetypes == null) - recommended: no-side effects == constant evaluation - conflicting with: 5.4.1.1e - order - out: - by value (copy, type compatiblity) - copy back - inout: - by reference (type euqality, strong typing) - incremential changes visible - implcit deference - no reference to elements of string types - default parameter - non-l-values (values of templates, defaults, ... must be `in` An _in-parameter_ is _passed by value_. A _out-parameter_ is also _passed by value_. A _inout-parameter_ is _passed by reference_. - expanding rules for referencing the elemnt on the left hand side. (6.2, 15.6) It is allowed to pass elements of structured values or templates (record, set, record of, set of, union and anytype values or templates) by reference. Modification of parameters passed this way affects the original structured value or template. Before passing the actual parameter, the rules for referencing the element on the left hand side of assignments are applied, expanding the structured value so that the referenced element becomes accessible (see clauses 6.2 and 15.6 for more details). ```ttcn3 example = "unintended side-effects" type component C { var integer cVar **Syntactical Description** ```ebnf ActualParList ::= "(" [ ActualPar {"," ActualPar} {"," ActualParAssignment} | ActualParAssignment {"," ActualParAssignment} ] ")". ActualPar ::= Expr | Expr "..." | "-". ActualParAssignment ::= name ":=" Expr. ``` In _list notation_, each actual parameter is an `ActualPar`. In _assignment notation_, each actual parameter is an `ActualParAssignment`. In _mixed notation_, one or more `ActualPar` entries are followed by one or more `ActualParAssignment` entries. The `...` suffix is used only when passing an actual parameter to a variadic formal parameter as described in [variadic parameters](#variadic-parameters). The `-` symbol is the omission marker in list notation. Its meaning for a default formal parameter remains unresolved pending [default parameters](#default-parameters). Its use for a variadic formal parameter is specified in [variadic parameters](#variadic-parameters). The parentheses of an empty actual parameter list may be omitted for a parameterized language element other than a function, external function, testcase, or altstep. **Semantic description** In list notation, actual parameters shall map by position: the first actual parameter maps to the first formal parameter, the second actual parameter maps to the second formal parameter, and so on. In assignment notation, each actual parameter shall map to the formal parameter whose name occurs before `:=`. That name shall identify a formal parameter of the invoked language element. The order of the formal parameter declarations does not determine the order of the actual parameter assignments. In mixed notation, the leading list entries shall map by position. Each following assignment entry shall map by name. An assignment entry shall not map to a formal parameter already mapped by a preceding list entry. Actual parameters shall be processed in their textual order in the actual parameter list, irrespective of the notation used. For each actual parameter, its expression shall be evaluated where applicable and the initial assignment or binding required by the mapped formal parameter's kind shall be completed before processing of the next actual parameter begins. The assignment and binding semantics for `in`, `out`, and `inout` parameters are specified below; subsequent copy-back semantics are not part of this initial processing order. An actual parameter expression shall be evaluated in the scope of the caller. Names in that expression therefore denote declarations visible at the point of invocation, not declarations in the invoked language element. As specified in [formal parameters](#formal-parameters), a formal parameter without an explicit direction is an `in` formal parameter. For an `in` formal parameter, the value of the actual parameter shall be assigned to distinct storage for the formal parameter before invocation. The type of the actual parameter shall be compatible with the type of the formal parameter. Subsequent assignment to the formal parameter shall not modify the actual parameter. For an `out` formal parameter, distinct storage shall be provided for the formal parameter. No value shall be copied from the actual parameter into that storage. The final value of the formal parameter shall be copied back to the actual parameter. The formal parameter type shall be compatible with the type of the writable actual location; this compatibility shall be checked before invocation. For an `inout` formal parameter, the actual parameter shall be bound by reference; no separate value shall be copied in or copied back. The type of the actual parameter shall be identical to the type of the formal parameter. Reading or assigning the formal parameter shall implicitly dereference that binding, and each assignment shall therefore be immediately observable through the actual parameter. Passing an actual parameter to a formal parameter shall have the assignment semantics of the mapped parameter kind. When an element of a structured value or structured template is passed to an `out` or `inout` formal parameter, the applicable left-hand-side element-reference and expansion rules shall be applied before the parameter is passed, so that the referenced element is accessible. An element of a record, set, `record of`, `set of`, union, or `anytype` value or template may be passed by reference when it otherwise satisfies the requirements for an `inout` actual parameter. Assignment through the formal parameter shall then modify that element of the original structured value or template. The actual parameters of parameterized templates and altsteps shall be governed by the `in` parameter semantics above because their formal parameters are restricted to `in` parameters. Their default and variadic actual parameters shall additionally follow [default parameters](#default-parameters) and [variadic parameters](#variadic-parameters), respectively. Clause 5.4.2 m prohibits aliasing structured values and unions within the same function. In permitted cases, such as the scalar component variable in the example below, two accessible names may denote the same location during an invocation; assignment through an `inout` formal parameter is then observable through either name. **Restrictions** 1. An `ActualPar` shall not follow an `ActualParAssignment` in the same actual parameter list. 2. Except for the list-notation rules for a [variadic parameter](#variadic-parameters), no formal parameter shall be mapped more than once in the same actual parameter list. 3. Each formal parameter that is neither a [default parameter](#default-parameters) nor a [variadic parameter](#variadic-parameters) shall be mapped exactly once. 4. The `-` omission marker shall not map to a formal parameter that is neither a default parameter nor a variadic parameter. 5. An actual parameter mapped to an `out` or `inout` formal parameter shall denote a writable location. A literal, expression result, constant, template value, or other non-left-hand-side value shall be mapped only to an `in` formal parameter. 6. Actual parameters of parameterized templates and altsteps shall be governed by `in` parameter semantics because their formal parameters are restricted to `in` parameters. 7. In accordance with clause 5.4.2 m, an actual parameter list shall not create prohibited aliases of structured values or unions within the same function. The omission rules for variadic parameters are specified in [variadic parameters](#variadic-parameters). The omission rules for default parameters remain unresolved pending rules in [default parameters](#default-parameters). > NOTE: The source term “midex notation” is treated as a typographical error > for _mixed notation_. The separate source fragment “assignment list > notation” is incomplete and remains unresolved. > NOTE: The source note `optional default value (referencetypes == null)` is > ambiguous as to whether it concerns omitted actual parameters, initial > values of reference types, or both. It remains unresolved; omission is > reserved for [default parameters](#default-parameters). > NOTE: The incomplete source fragment about non-left-hand-side values lists > “defaults” without defining what kind of expression that term denotes. > Whether it identifies an additional category remains unresolved. > NOTE: The source prohibits passing an element of a string value to an > `inout` formal parameter. The existing formal-parameter restriction more > broadly prohibits string-type `inout` parameters, so no example can isolate > the actual-parameter restriction. Their intended relationship remains > unresolved. > NOTE: Actual parameter expressions without side effects are recommended. > The relationship of this recommendation to clause 5.4.1.1e remains to be > resolved. > NOTE: The behavior when an `out` formal parameter is not assigned, the point > at which copy-back occurs, and the order of copy-back for multiple `out` > parameters are not established by the source notes and remain unresolved. > Whether `-` may discard an `out` result also remains unresolved and requires > a rule in [default parameters](#default-parameters). The handling of a > copied-back value that is outside the actual location's subtype or range also > remains unresolved. > NOTE: The source note “special rules altsteps, templates” does not identify > any rule beyond the `in`-only restriction and the default and variadic rules > cross-referenced above. Any additional rule remains unresolved and requires > an authoritative source. > NOTE: The [default parameters](#default-parameters) subsection does not yet > specify omission or `-` behavior. Those cases remain unresolved here rather > than being inferred. > NOTE: The variadic subsection states both that an omitted or `-` actual > parameter produces an empty `record of` value or template and, in its > “default parameter” example, that the declared default is used. The > precedence between these rules remains unresolved; the cross-reference does > not settle this conflict. > NOTE: The source identifies the left-hand-side element-reference and > expansion rules as clauses 6.2 and 15.6, but corresponding targets are not > available in the current Markdown sources. Their exact identification and > cross-references remain unresolved. > NOTE: How the aliasing prohibition of clause 5.4.2 m can be enforced, > particularly when aliases arise through structured elements, remains > unresolved. > NOTE: Passing variables of components as `inout` parameters can cause > unintended side effects and should be avoided. > NOTE: The source's incomplete “pass reference by reference” component > example does not contain an invocation or assignment. The intended behavior > remains unresolved and requires a complete requirement before a normative > example can be provided. > NOTE: The source's empty “pass by value: changes not visible” example has > been completed by the observable `changeCopy` example below. **Examples** ```ttcn3 example="actual parameter notation" function f(integer p, integer q, integer r) {} control { f(1, 2, 3); // list notation f(p := 1, q := 2, r := 3); // assignment notation f(1, q := 2, r := 3); // mixed notation f(p := 1, 2, 3); // error: list entry follows assignment } ``` function f(inout integer p) runs on C { cVar := 10; p := 99; // changing p also changes cVar, because both are // references to the same piece of data. ```ttcn3 example="positional mapping" function check(integer first, integer second, integer third) { // expect: first == 1, second == 2, third == 3 } log(cVar); // expected output: 99 control { check(1, 2, 3); } ``` ```ttcn3 example="named mapping and evaluation order" function next(inout integer n) return integer { n := n + 1; return n; } testcase tc() runs on C { f(cVar); function check(integer first, integer second, integer third) { log(first, second, third); // logs 2, 1, 3 } control { var integer n := 0; check(second := next(n), first := next(n), third := next(n)); // The expressions are evaluated in textual order, not formal-parameter order. } ``` ```ttcn3 example="each invocation has its own copy" ```ttcn3 example="mixed mapping and evaluation order" function next(inout integer n) return integer { n := n + 1; return n; } // each invocation of function `fib` has its own copy of parameter n. function fib(in integer n) return integer { function check(integer first, integer second, integer third) { log(first, second, third); // logs 1, 3, 2 } control { var integer n := 0; check(next(n), third := next(n), second := next(n)); // The positional entry maps first; named entries map and run as written. } ``` ```ttcn3 example="invalid duplicate mapping" function f(integer p, integer q) {} control { f(1, p := 2); // error: p is mapped twice f(p := 1, p := 2); // error: p is mapped twice } ``` ```ttcn3 example="invalid named and missing mappings" function f(integer p, integer q) {} control { f(p := 1, unknown := 2); // error: unknown is not a formal parameter f(p := 1); // error: required formal parameter q is not mapped } ``` ```ttcn3 example="invalid omission of required parameter" function f(integer required) {} control { f(-); // error: required is neither default nor variadic } ``` ```ttcn3 example="evaluation in caller scope" const integer offset := 1; function add(integer value) return integer { const integer offset := 100; return value; } control { var integer base := 2; var integer result := add(base + offset); log(result); // logs 3, because offset is resolved in the caller's scope } ``` ```ttcn3 example="omitted empty actual parameter list" template integer one() := 1; template integer alsoOne := one; // equivalent to one() ``` ```ttcn3 example="in parameter uses a compatible copy" type integer Small (0..10); function changeCopy(in integer p) { p := 9; } control { var Small n := 2; changeCopy(n); // Small is compatible with integer log(n); // logs 2: p has distinct storage } ``` ```ttcn3 example="each invocation has its own parameter copy" function fibonacci(in integer n) return integer { if (n < 2) { return 1 return 1; } return fib(n-2) + fib(n-1) return fibonacci(n - 2) + fibonacci(n - 1); } control { var integer v := fib(2); // expect: v == 2 var integer result := fibonacci(2); log(result); // logs 2 } ``` ```ttcn3 example="pass by value: changes not visible" function f(in integer i) { ```ttcn3 example="out parameter copies its final value back" type integer Small (0..10); function produce(out integer p) { p := 7; } control { var Small result := 0; produce(result); log(result); // logs 7: compatible types need not be identical } ``` ```ttcn3 example="pass by reference" function f(inout integer i) { i := i + 1; ```ttcn3 example="inout parameter is implicitly dereferenced" function increment(inout integer p) { p := p + 1; log(p); // logs 2 through the binding to n } control { var integer i := 0; f(i) log(i) // expected output: 1 var integer n := 1; increment(n); log(n); // logs 2 } ``` ```ttcn3 example="pass reference by reference" // TODO: write test to change the passed inout variable to type component PTC {} ```ttcn3 example="invalid compatible but non-identical inout type" type integer Small (0..10); testcase tc() { var PTC a := PTC.create("a"); var PTC b := PTC.create("b"); function increment(inout integer p) { p := p + 1; } var PTC c; control { var Small n := 1; increment(n); // error: compatible types are not sufficient for inout } ``` ```ttcn3 example="invalid non-lvalue actual parameters" const integer fixed := 0; template integer pattern := 1; function setOut(out integer p) { p := 1; } function setInout(inout integer p) { p := 1; } control { setOut(0); // error: a literal is not a writable location setInout(1 + 2); // error: an expression result is not a writable location setOut(fixed); // error: a constant is not writable setOut(pattern); // error: a template value is not a writable value } ``` ```ttcn3 example="invalid incompatible in and out types" function consume(in integer p) { } function produce(out integer p) { p := 1; } control { var charstring text := "x"; consume(text); // error: charstring is not compatible with integer produce(text); // error: integer cannot be copied back to charstring } ``` ```ttcn3 example="structured element passed by reference" type record Pair { integer left, integer right } > NOTE: Passing variables of components as inout-parameter can cause unintended > side-effects, and should be avoided. function increment(inout integer p) { p := p + 1; } control { var Pair pair := { left := 1, right := 2 }; increment(pair.left); log(pair); // logs { left := 2, right := 2 } } ``` ```ttcn3 example="structured element receives out copy-back" type record Pair { integer left, integer right } function produce(out integer p) { p := 7; } control { var Pair pair := { left := 1, right := 2 }; produce(pair.right); log(pair); // logs { left := 1, right := 7 } } ``` ```ttcn3 example="structured template element passed by reference" type record Pair { integer left, integer right } function replace(inout template integer p) { p := 3; } control { var template Pair pattern := { left := 1, right := ? }; replace(pattern.left); log(pattern); // logs { left := 3, right := ? } } ``` ```ttcn3 example="unintended side effects" type component C { var integer cVar; } function f(inout integer p) runs on C { cVar := 10; p := 99; // changing p also changes cVar, because both are // references to the same piece of data. log(cVar); // expected output: 99 } testcase tc() runs on C { f(cVar); } ``` ### Default parameters Loading Loading
src/16-declaring-dynamic-behaviour.md +436 −84 Original line number Diff line number Diff line Loading @@ -180,126 +180,478 @@ control { ### Actual parameters An _actual parameter list_ supplies parameters to an invocation or instantiation of a parameterized TTCN-3 language element. An _actual parameter list_ may be written using _list notation_, _assignment notation_, or _mixed notation_. - empty parameter list may be omitted for parameterized object that are not functions, testcase, altstep, external functions - notations - list notation - assignment notation (evaluated in order of actual arguments) - midex notation - passing an parameter to a formal parameter is semantically equivalent to an assignment. - this implies that value expansion is (left-hand side reference semantics) - 5.4.2.m aliasing (of structs and unions) in the same function is forbidden (can we actually enforce that?) - actual parameters are mapped on the - evaluated in the order they are passed - evaluated in the scope of the caller _- assignment list notation - special rules altsteps, templates - parameter kind: - in (default): - by value (copy, type compatibility) - optional default value (referencetypes == null) - recommended: no-side effects == constant evaluation - conflicting with: 5.4.1.1e - order - out: - by value (copy, type compatiblity) - copy back - inout: - by reference (type euqality, strong typing) - incremential changes visible - implcit deference - no reference to elements of string types - default parameter - non-l-values (values of templates, defaults, ... must be `in` An _in-parameter_ is _passed by value_. A _out-parameter_ is also _passed by value_. A _inout-parameter_ is _passed by reference_. - expanding rules for referencing the elemnt on the left hand side. (6.2, 15.6) It is allowed to pass elements of structured values or templates (record, set, record of, set of, union and anytype values or templates) by reference. Modification of parameters passed this way affects the original structured value or template. Before passing the actual parameter, the rules for referencing the element on the left hand side of assignments are applied, expanding the structured value so that the referenced element becomes accessible (see clauses 6.2 and 15.6 for more details). ```ttcn3 example = "unintended side-effects" type component C { var integer cVar **Syntactical Description** ```ebnf ActualParList ::= "(" [ ActualPar {"," ActualPar} {"," ActualParAssignment} | ActualParAssignment {"," ActualParAssignment} ] ")". ActualPar ::= Expr | Expr "..." | "-". ActualParAssignment ::= name ":=" Expr. ``` In _list notation_, each actual parameter is an `ActualPar`. In _assignment notation_, each actual parameter is an `ActualParAssignment`. In _mixed notation_, one or more `ActualPar` entries are followed by one or more `ActualParAssignment` entries. The `...` suffix is used only when passing an actual parameter to a variadic formal parameter as described in [variadic parameters](#variadic-parameters). The `-` symbol is the omission marker in list notation. Its meaning for a default formal parameter remains unresolved pending [default parameters](#default-parameters). Its use for a variadic formal parameter is specified in [variadic parameters](#variadic-parameters). The parentheses of an empty actual parameter list may be omitted for a parameterized language element other than a function, external function, testcase, or altstep. **Semantic description** In list notation, actual parameters shall map by position: the first actual parameter maps to the first formal parameter, the second actual parameter maps to the second formal parameter, and so on. In assignment notation, each actual parameter shall map to the formal parameter whose name occurs before `:=`. That name shall identify a formal parameter of the invoked language element. The order of the formal parameter declarations does not determine the order of the actual parameter assignments. In mixed notation, the leading list entries shall map by position. Each following assignment entry shall map by name. An assignment entry shall not map to a formal parameter already mapped by a preceding list entry. Actual parameters shall be processed in their textual order in the actual parameter list, irrespective of the notation used. For each actual parameter, its expression shall be evaluated where applicable and the initial assignment or binding required by the mapped formal parameter's kind shall be completed before processing of the next actual parameter begins. The assignment and binding semantics for `in`, `out`, and `inout` parameters are specified below; subsequent copy-back semantics are not part of this initial processing order. An actual parameter expression shall be evaluated in the scope of the caller. Names in that expression therefore denote declarations visible at the point of invocation, not declarations in the invoked language element. As specified in [formal parameters](#formal-parameters), a formal parameter without an explicit direction is an `in` formal parameter. For an `in` formal parameter, the value of the actual parameter shall be assigned to distinct storage for the formal parameter before invocation. The type of the actual parameter shall be compatible with the type of the formal parameter. Subsequent assignment to the formal parameter shall not modify the actual parameter. For an `out` formal parameter, distinct storage shall be provided for the formal parameter. No value shall be copied from the actual parameter into that storage. The final value of the formal parameter shall be copied back to the actual parameter. The formal parameter type shall be compatible with the type of the writable actual location; this compatibility shall be checked before invocation. For an `inout` formal parameter, the actual parameter shall be bound by reference; no separate value shall be copied in or copied back. The type of the actual parameter shall be identical to the type of the formal parameter. Reading or assigning the formal parameter shall implicitly dereference that binding, and each assignment shall therefore be immediately observable through the actual parameter. Passing an actual parameter to a formal parameter shall have the assignment semantics of the mapped parameter kind. When an element of a structured value or structured template is passed to an `out` or `inout` formal parameter, the applicable left-hand-side element-reference and expansion rules shall be applied before the parameter is passed, so that the referenced element is accessible. An element of a record, set, `record of`, `set of`, union, or `anytype` value or template may be passed by reference when it otherwise satisfies the requirements for an `inout` actual parameter. Assignment through the formal parameter shall then modify that element of the original structured value or template. The actual parameters of parameterized templates and altsteps shall be governed by the `in` parameter semantics above because their formal parameters are restricted to `in` parameters. Their default and variadic actual parameters shall additionally follow [default parameters](#default-parameters) and [variadic parameters](#variadic-parameters), respectively. Clause 5.4.2 m prohibits aliasing structured values and unions within the same function. In permitted cases, such as the scalar component variable in the example below, two accessible names may denote the same location during an invocation; assignment through an `inout` formal parameter is then observable through either name. **Restrictions** 1. An `ActualPar` shall not follow an `ActualParAssignment` in the same actual parameter list. 2. Except for the list-notation rules for a [variadic parameter](#variadic-parameters), no formal parameter shall be mapped more than once in the same actual parameter list. 3. Each formal parameter that is neither a [default parameter](#default-parameters) nor a [variadic parameter](#variadic-parameters) shall be mapped exactly once. 4. The `-` omission marker shall not map to a formal parameter that is neither a default parameter nor a variadic parameter. 5. An actual parameter mapped to an `out` or `inout` formal parameter shall denote a writable location. A literal, expression result, constant, template value, or other non-left-hand-side value shall be mapped only to an `in` formal parameter. 6. Actual parameters of parameterized templates and altsteps shall be governed by `in` parameter semantics because their formal parameters are restricted to `in` parameters. 7. In accordance with clause 5.4.2 m, an actual parameter list shall not create prohibited aliases of structured values or unions within the same function. The omission rules for variadic parameters are specified in [variadic parameters](#variadic-parameters). The omission rules for default parameters remain unresolved pending rules in [default parameters](#default-parameters). > NOTE: The source term “midex notation” is treated as a typographical error > for _mixed notation_. The separate source fragment “assignment list > notation” is incomplete and remains unresolved. > NOTE: The source note `optional default value (referencetypes == null)` is > ambiguous as to whether it concerns omitted actual parameters, initial > values of reference types, or both. It remains unresolved; omission is > reserved for [default parameters](#default-parameters). > NOTE: The incomplete source fragment about non-left-hand-side values lists > “defaults” without defining what kind of expression that term denotes. > Whether it identifies an additional category remains unresolved. > NOTE: The source prohibits passing an element of a string value to an > `inout` formal parameter. The existing formal-parameter restriction more > broadly prohibits string-type `inout` parameters, so no example can isolate > the actual-parameter restriction. Their intended relationship remains > unresolved. > NOTE: Actual parameter expressions without side effects are recommended. > The relationship of this recommendation to clause 5.4.1.1e remains to be > resolved. > NOTE: The behavior when an `out` formal parameter is not assigned, the point > at which copy-back occurs, and the order of copy-back for multiple `out` > parameters are not established by the source notes and remain unresolved. > Whether `-` may discard an `out` result also remains unresolved and requires > a rule in [default parameters](#default-parameters). The handling of a > copied-back value that is outside the actual location's subtype or range also > remains unresolved. > NOTE: The source note “special rules altsteps, templates” does not identify > any rule beyond the `in`-only restriction and the default and variadic rules > cross-referenced above. Any additional rule remains unresolved and requires > an authoritative source. > NOTE: The [default parameters](#default-parameters) subsection does not yet > specify omission or `-` behavior. Those cases remain unresolved here rather > than being inferred. > NOTE: The variadic subsection states both that an omitted or `-` actual > parameter produces an empty `record of` value or template and, in its > “default parameter” example, that the declared default is used. The > precedence between these rules remains unresolved; the cross-reference does > not settle this conflict. > NOTE: The source identifies the left-hand-side element-reference and > expansion rules as clauses 6.2 and 15.6, but corresponding targets are not > available in the current Markdown sources. Their exact identification and > cross-references remain unresolved. > NOTE: How the aliasing prohibition of clause 5.4.2 m can be enforced, > particularly when aliases arise through structured elements, remains > unresolved. > NOTE: Passing variables of components as `inout` parameters can cause > unintended side effects and should be avoided. > NOTE: The source's incomplete “pass reference by reference” component > example does not contain an invocation or assignment. The intended behavior > remains unresolved and requires a complete requirement before a normative > example can be provided. > NOTE: The source's empty “pass by value: changes not visible” example has > been completed by the observable `changeCopy` example below. **Examples** ```ttcn3 example="actual parameter notation" function f(integer p, integer q, integer r) {} control { f(1, 2, 3); // list notation f(p := 1, q := 2, r := 3); // assignment notation f(1, q := 2, r := 3); // mixed notation f(p := 1, 2, 3); // error: list entry follows assignment } ``` function f(inout integer p) runs on C { cVar := 10; p := 99; // changing p also changes cVar, because both are // references to the same piece of data. ```ttcn3 example="positional mapping" function check(integer first, integer second, integer third) { // expect: first == 1, second == 2, third == 3 } log(cVar); // expected output: 99 control { check(1, 2, 3); } ``` ```ttcn3 example="named mapping and evaluation order" function next(inout integer n) return integer { n := n + 1; return n; } testcase tc() runs on C { f(cVar); function check(integer first, integer second, integer third) { log(first, second, third); // logs 2, 1, 3 } control { var integer n := 0; check(second := next(n), first := next(n), third := next(n)); // The expressions are evaluated in textual order, not formal-parameter order. } ``` ```ttcn3 example="each invocation has its own copy" ```ttcn3 example="mixed mapping and evaluation order" function next(inout integer n) return integer { n := n + 1; return n; } // each invocation of function `fib` has its own copy of parameter n. function fib(in integer n) return integer { function check(integer first, integer second, integer third) { log(first, second, third); // logs 1, 3, 2 } control { var integer n := 0; check(next(n), third := next(n), second := next(n)); // The positional entry maps first; named entries map and run as written. } ``` ```ttcn3 example="invalid duplicate mapping" function f(integer p, integer q) {} control { f(1, p := 2); // error: p is mapped twice f(p := 1, p := 2); // error: p is mapped twice } ``` ```ttcn3 example="invalid named and missing mappings" function f(integer p, integer q) {} control { f(p := 1, unknown := 2); // error: unknown is not a formal parameter f(p := 1); // error: required formal parameter q is not mapped } ``` ```ttcn3 example="invalid omission of required parameter" function f(integer required) {} control { f(-); // error: required is neither default nor variadic } ``` ```ttcn3 example="evaluation in caller scope" const integer offset := 1; function add(integer value) return integer { const integer offset := 100; return value; } control { var integer base := 2; var integer result := add(base + offset); log(result); // logs 3, because offset is resolved in the caller's scope } ``` ```ttcn3 example="omitted empty actual parameter list" template integer one() := 1; template integer alsoOne := one; // equivalent to one() ``` ```ttcn3 example="in parameter uses a compatible copy" type integer Small (0..10); function changeCopy(in integer p) { p := 9; } control { var Small n := 2; changeCopy(n); // Small is compatible with integer log(n); // logs 2: p has distinct storage } ``` ```ttcn3 example="each invocation has its own parameter copy" function fibonacci(in integer n) return integer { if (n < 2) { return 1 return 1; } return fib(n-2) + fib(n-1) return fibonacci(n - 2) + fibonacci(n - 1); } control { var integer v := fib(2); // expect: v == 2 var integer result := fibonacci(2); log(result); // logs 2 } ``` ```ttcn3 example="pass by value: changes not visible" function f(in integer i) { ```ttcn3 example="out parameter copies its final value back" type integer Small (0..10); function produce(out integer p) { p := 7; } control { var Small result := 0; produce(result); log(result); // logs 7: compatible types need not be identical } ``` ```ttcn3 example="pass by reference" function f(inout integer i) { i := i + 1; ```ttcn3 example="inout parameter is implicitly dereferenced" function increment(inout integer p) { p := p + 1; log(p); // logs 2 through the binding to n } control { var integer i := 0; f(i) log(i) // expected output: 1 var integer n := 1; increment(n); log(n); // logs 2 } ``` ```ttcn3 example="pass reference by reference" // TODO: write test to change the passed inout variable to type component PTC {} ```ttcn3 example="invalid compatible but non-identical inout type" type integer Small (0..10); testcase tc() { var PTC a := PTC.create("a"); var PTC b := PTC.create("b"); function increment(inout integer p) { p := p + 1; } var PTC c; control { var Small n := 1; increment(n); // error: compatible types are not sufficient for inout } ``` ```ttcn3 example="invalid non-lvalue actual parameters" const integer fixed := 0; template integer pattern := 1; function setOut(out integer p) { p := 1; } function setInout(inout integer p) { p := 1; } control { setOut(0); // error: a literal is not a writable location setInout(1 + 2); // error: an expression result is not a writable location setOut(fixed); // error: a constant is not writable setOut(pattern); // error: a template value is not a writable value } ``` ```ttcn3 example="invalid incompatible in and out types" function consume(in integer p) { } function produce(out integer p) { p := 1; } control { var charstring text := "x"; consume(text); // error: charstring is not compatible with integer produce(text); // error: integer cannot be copied back to charstring } ``` ```ttcn3 example="structured element passed by reference" type record Pair { integer left, integer right } > NOTE: Passing variables of components as inout-parameter can cause unintended > side-effects, and should be avoided. function increment(inout integer p) { p := p + 1; } control { var Pair pair := { left := 1, right := 2 }; increment(pair.left); log(pair); // logs { left := 2, right := 2 } } ``` ```ttcn3 example="structured element receives out copy-back" type record Pair { integer left, integer right } function produce(out integer p) { p := 7; } control { var Pair pair := { left := 1, right := 2 }; produce(pair.right); log(pair); // logs { left := 1, right := 7 } } ``` ```ttcn3 example="structured template element passed by reference" type record Pair { integer left, integer right } function replace(inout template integer p) { p := 3; } control { var template Pair pattern := { left := 1, right := ? }; replace(pattern.left); log(pattern); // logs { left := 3, right := ? } } ``` ```ttcn3 example="unintended side effects" type component C { var integer cVar; } function f(inout integer p) runs on C { cVar := 10; p := 99; // changing p also changes cVar, because both are // references to the same piece of data. log(cVar); // expected output: 99 } testcase tc() runs on C { f(cVar); } ``` ### Default parameters Loading