STRUCTURE-ENDSTRUCTURE

Define how data is laid out

WSupported on Windows
USupported on Unix
VSupported on OpenVMS
NSupported in Synergy .NET
[access] [structure_mod] STRUCTURE name[<T[(constraints)], ...>]
  member_def
  .
  .
  .
[ENDSTRUCTURE]

access

(optional) For a class structure only, one of the following access modifiers:

PUBLIC

Access is not restricted. This is the most accessible option. (default)

PROTECTED

Access is limited to the containing class or types derived from the containing class. (traditional Synergy only)

PRIVATE

Access is limited to the containing type. This is the least accessible option. (traditional Synergy only)

INTERNAL

Access is limited to the current assembly. (Synergy .NET only)

structure_mod

(optional) One or more of the following structure modifiers:

BYREF

Indicates the structure can only be allocated on the stack and has restrictions on its usage. (Synergy .NET only)

CLS

The structure is a .NET value type structure. If CLS is not specified, a Synergy structure is generated.

PARTIAL

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.

READONLY

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:

Multiple constraints must be separated by commas. See Constraints for more information. (Synergy .NET only)

member_def

Either the definition of a single field or a group declaration. Each field definition has the syntax described in Defining a field. Each group declaration has the syntax described in GROUP-ENDGROUP. 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 .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. 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 cannot have overlays, and they cannot be used with ^M, passed as alpha arguments, or declared as real arrays (only dynamic arrays). CLS structures cannot contain groups or Synergy a, d, d., or i types. However, a Synergy structure can contain a CLS structure. CLS structfields are more efficient than Synergy structfields.

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

Note

Synergy global structures used as attribute arguments for Interop projects must be defined in an assembly outside of a namespace.

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