STRUCTURE-ENDSTRUCTURE
|
WSupported on Windows
|
USupported on Unix
|
VSupported on OpenVMS
|
NSupported in Synergy .NET
|
[access] [structure_mod] STRUCTURE name[<T[(constraints)], ...>] & [IMPLEMENTS interface[, ...] member_def . . . [ENDSTRUCTURE]
Arguments
access
(optional) For a class structure only, one of the following access modifiers:
Access is not restricted. This is the most accessible option. (default)
Access is limited to the containing class or types derived from the containing class. (traditional Synergy only)
Access is limited to the containing type. This is the least accessible option. (traditional Synergy only)
Access is limited to the current assembly. (Synergy .NET only)
structure_mod
(optional) One or more of the following structure modifiers:
Indicates the structure can only be allocated on the stack and has restrictions on its usage. (Synergy .NET only)
The structure is a .NET value type structure. If CLS is not specified, a Synergy structure is generated.
The structure declaration can be separated into two or more declarations that will be compiled together as a single structure. Partial structures may span one or more source files.
Ensures that all members of the structure are read-only and that it is only used in read-only scenarios. This enforcement adds a layer of correctness to code. (Synergy .NET only)
name
The name of the structure area to define.
T
A generic type parameter, which indicates the structure is a generic type and which acts as a a placeholder for which an actual type will be substituted when the member is used. Note that you can use any unused letter (not just T). See Generic types (.NET) for more information. (Synergy .NET only)
constraints
One or more of the following constraints:
- A base class, to stipulate that the generic type parameter must inherit from that specific base class. If no base class is specified, the default is System.Object.
- One or more interfaces, to stipulate that the generic type parameter must implement the specified interfaces.
- A constructor, to allow creating an instance of the type parameter using the NEW syntax.
Multiple constraints must be separated by commas. See Constraints for more information. (Synergy .NET only)
IMPLEMENTS
(optional) Indicates that a list of interfaces implemented by the structure follows. (Synergy .NET only)
interface
One or more interfaces that the structure implements, separated by commas. This clause is valid only on a structure declared with both the CLS and BYREF modifiers and that is declared globally or within a namespace or class, not on a structure declared locally within the data section of a method. It is not supported on other structure types. For each interface listed, the structure must declare a public method, property, or event that matches every member of that interface, with an identical signature. An error will occur if any interface member is missing or doesn't match. (Synergy .NET only)
member_def
A field definition, a group declaration, or (in Synergy .NET only) a method, property, or event member. Each field definition has the syntax described in Defining a field. Each group declaration has the syntax described in GROUP-ENDGROUP. Method, property, and event members follow the same rules as when declared in a class; see METHOD-ENDMETHOD, PROPERTY-ENDPROPERTY, and EVENT, respectively. You can specify as many member definitions as you want.
Discussion
The STRUCTURE statement defines how data is laid out. Unlike the RECORD statement, it does not allocate any data space. A structure can be declared globally or within a namespace, class, or routine.
A structure declared globally or within a namespace or class can be used as a data type for a field, parameter, return type, property, or local variable. See structure for more information.
A structure declared in an implicit main routine before any record construct is considered to be a member of the global namespace. If you want to declare a structure within an implicit main routine, add an explicit MAIN or RECORD before the structure declaration. For example,
structure struct1 ;Structure in global namespace
fld1, i4
endstructure
record
structure struct2 ;Structure is declared locally to implicit main
fld2, i4
endstructure
Structures within a routine can be used only as the first operand of the ^M data reference operation, as an argument to a ^SIZE operation, or as the type of a struct field in a record or a local DATA statement within the same routine. Any other type of reference generates a compilation error. The resulting data structure has an implied [*] dimension specification. This single-dimension specification allows array access of the format
^m(structure[n],memory_handle)
where n is limited to the size of the structure divided into the size of the memory handle.
For example, given a structure defined with the name str and a field fld, the following field expression is always allowed:
^m(str[n].fld,handle)
^M of a structure that has an object field generates an error, because you can’t map an object on memory.
When used in a dynamic array, an initial value declared in a structure is propagated to each element of the array
The ENDSTRUCTURE statement is optional but recommended. If not specified, the structure is automatically terminated at the start of the next syntactical component. (Note, however, that depending on what the next component is, there are rare instances, such as with the xfMethod attribute, when the compiler cannot terminate the structure properly, and you must specify ENDSTRUCTURE.) When declaring a global structure, explicitly specifying ENDSTRUCTURE is recommended, and the compiler issues an “ENDSTRUCTURE on global structure expected” (NOSPECL) warning if it is omitted.
|
|
Synergy global structures used as attribute arguments for Interop projects must be defined in an assembly outside of a namespace. |
CLS structures
Synergy .NET supports both Synergy structures and .NET structures. A .NET structure is defined by specifying the CLS modifier on the STRUCTURE statement; if CLS is not specified, the structure is considered to be a Synergy structure. CLS structfields are more efficient than Synergy structfields. A Synergy structure can contain a CLS structure.
Structures defined in other languages, such as C#, are marked as CLS structures and handled as such within the Synergy .NET compiler. Only CLS structures can be passed between .NET languages. They can't have overlays or be used with ^M, passed as alpha arguments, or declared as real arrays (only dynamic), and they can't contain groups or Synergy a, d, d., or i types. A CLS structure can contain an inline array.
A BYREF structure is created to be passed by reference in method arguments or reference returns. Such structures cannot be used from the heap or with any of the following: generic arguments, boxed objects, lambdas, YIELD iterators, or ASYNC methods, or a semantic error will occur. The BYREF modifier can only be used on a CLS structure, and a BYREF structure must be used as a type for another BYREF declaration (BYREF local data, BYREF return, BYREF parameter, or field within a BYREF structure).
A BYREF CLS structure can also implement one or more interfaces by adding an IMPLEMENTS clause after the structure name, followed by a comma-separated list of interface names. This is only supported for a structure declared globally or within a namespace or class; a local BYREF CLS structure (one declared within the data section of a method) cannot specify IMPLEMENTS or provide members that implement an interface. For example,
public byref cls structure rstruct1 implements iface1
.
.
.
endstructure
For each interface listed, the structure must supply a public method, property, or event that matches every member declared by that interface, with an identical signature; the compiler generates an error if any interface member is missing or its signature doesn't match. Implementing an interface allows an instance of the structure to be used wherever that interface is expected, for example, as an argument to a generic method or class whose type parameter is constrained to one or more interfaces.
A structure that implements an interface must supply a public method, property, or event matching each member the interface declares. Unlike a class, however, a BYREF structure cannot be assigned to a variable of the interface type (for example, data ivar, @iface1; ivar = rvar is not valid), because BYREF structures cannot be boxed. Instead, to call an interface member through a BYREF structure, you must access it through a generic type parameter constrained to that interface with the allowbyref modifier. See Constraints for more information and an example.
See also
Examples
The following example declares a public structure called mystruct that contains two fields.
public structure mystruct
field1 ,i4
field2 ,a20
endstructure
main
record
str ,mystruct
proc
str.field1 = 7
end
The example below defines two interfaces, iface1 and iface2, and a BYREF CLS structure, rstruct1, that implements both by providing matching public methods. The main routine creates an instance of rstruct1 and calls its interface methods directly.
public interface iface1
method meth1, void
endmethod
endinterface
public interface iface2
method meth2, void
endmethod
endinterface
public byref cls structure rstruct1 implements iface1, iface2
fld1, int
public method meth1, void
proc
console.writeline("- rstruct1.meth1")
endmethod
public method meth2, void
proc
console.writeline("- rstruct1.meth2")
endmethod
endstructure
main
proc
data rvar = new rstruct1()
rvar.meth1()
rvar.meth2()
endmain
