Rules for passing one type to another

You can assign the following types interchangeably in an assignment statement. Implicit conversions are performed.

The string type has the same implicit conversions as the alpha type. Booleans can be assigned to or from any of the signed integer types.

You can pass the following types interchangeably as an argument to an IN parameter:

You can pass the following types interchangeably as an argument to an IN numeric parameter or a parameter without a specified direction:

Int arguments can only be passed to int, n, or n.

The default passing convention is ^DESCR in traditional Synergy or BYVAL in Synergy .NET. When using BYREF in Synergy .NET, types must match exactly for the following types:

If the parameter has a MISMATCH modifier, you can pass the following:

You can also pass an a type to an OUT or INOUT non-CLS structure.

You can assign the following types to the listed Synergy object type in an assignment statement or as the value of an IN parameter:

Passing One Type to Another

Destination type

Source type

sbyte, i2

i1

short, i4

i2

int, i8

i4

long, d

i8

decimal, d.

d

n, n.

d

i1, short

sbyte

i2, int

short

i4, long

int

ushort

byte

uint

ushort

ulong

uint

decimal

ulong

double

float

decimal

double

d., n, n.

decimal

@class

An instance of class, or a derived class, or the cast of a class that has an explicit operator to convert to the destination type (see Conversion operators for more information)

@*

Any class instance, any interface (Synergy .NET only), or any boxed value type

@interface

The same interface, or a cast of another interface or class variable to this interface (Synergy .NET only)

@delegate

An instance of the same delegate, or a cast of a System.Object variable or method to this delegate (Synergy .NET only)

structure

Only the specified structure

enumeration

The same enumeration, one of the enumeration values, or a cast of another enumeration type or integer to this enumeration

You can cast an object variable to a specific type to perform an explicit conversion between the types. (See Conversion operators for user-defined explicit conversions for classes.) For example,

record
    obj1, @class1
    obj2, @class2
proc
    obj1 = new class1()
    obj2 = (class2)obj1         ;Invokes an op_Explicit that takes @class1 
                                ; and returns @class2

For non-object code, the difference between casting and converting is that while casting simply looks at the data as if it were a certain type without modifying its contents, converting changes the content to an appropriate representation of the semantic value of the original for the new type. For example, ^A (or %A) performs a cast to alpha type, while %STRING converts to alpha. Passing a value into an argument that is declared as alpha performs an implicit cast to alpha; assigning a value to an alpha variable invokes an implicit conversion to alpha.

Here’s a non-object example:

record
    alpha, a1, "A"
    num, i1
proc
    num = ^i(alpha)             ;num now contains 65
end
Note

We strongly recommend that you don’t cast the result of an expression because you cannot rely on the size or precision of the result. Use the conversion functions instead (%DECML, %IMPLIED, %INTEGER, %STRING, or %ZONED).

If you name a class record or a routine record, you can use that name to reference all the fields as one record for use in ISAM routines as one contiguous block of memory whose size is based on the sum of the declared fields’ sizes.

Passing different types of argument qualifiers

The table below compares how different types of argument qualifiers are passed in C#, traditional Synergy, and Synergy .NET.

 

C#

Traditional Synergy

Synergy .NET

Method parameter

Unspecified means BYVAL

Unspecified means IN

Unspecified means IN BYVAL

Subroutine/
function parameter

N/A

Unspecified means INOUT but literals can be passed; called routine to test if literal before writing

Unspecified means INOUT but literals can be passed; called routine to test if literal before writing

BYVAL (C# unspecified)

A copy of the variable is passed and can be locally modified in the called routine. The contents of a BYVAL object can be modified, affecting the contents of the passed object unless an assignment is performed on the BYVAL parameter first

N/A

BYVAL means read (IN) only. INOUT can be added to get identical behavior to C#

BYREF (C# REF/OUT)

Implied READ/WRITE, the object handle or value type can be updated in the calling routine

N/A

Implied READ/WRITE, the object handle or value type can be replaced

IN

Local copy allowed to be modified

Contents of object can be modified, parameters are immutable

IN BYVAL, contents of object can be modified, parameters are immutable

BYVAL CLS structure

Local changes modify the copy passed

N/A

Local changes modify the copy passed

Synergy structure

N/A

Local changes affect the caller’s data unless marked IN

Local changes affect the caller’s data unless marked IN

Unprototyped routine

N/A

No compiler checking for literals passed to OUT or INOUT parameters. Warnings for objects passed to a routine

N/A

^VAL

IntPtr

Native int based on the platform on which it’s run

Native int based on the platform on which it’s run

The types a, d, and i are Synergex descriptor types. When passed as arguments, the descriptors themselves are immutable. Only the contents can change (for example, the alpha value is modified based on OUT or INOUT rules).

The following sample demonstrates the above behavior in Synergy.

cls structure mys           ;.NET structure (CLS ignored in traditional)
vars,       int
endstructure
structure myss              ;Synergy structure
vars,       int
endstructure
namespace will
    public class jeff
        public var1,   int
    endclass
endnamespace
main
record
    fred,    @will.jeff
    myf,     mys
    myfs,    myss
    ab,            a10
    newint,  int
proc
    open(15,o,'tt:')
    fred = new will.jeff()
    xcall frank(fred, myf, myfs, ab, 1, newint)  ;Note myf passed as
                                                 ; value type
    writes(15,%string(fred.var1))                ; Should be 2
    writes(15,%string(myf.vars))                 ; Should be 0
    writes(15,%string(myfs.vars))                ; Should be 2
    writes(15,ab)                                ; Should be abcr
end
subroutine frank
    in fred,     @will.jeff
    in joe,      mys
.ifndef dblnet
    jim,         myss
    var,         a10
.else
    byval jim,   myss
    byval var,   a10
.endc
    myi,         int
    in newint,   int
proc
    jim.vars = 2
.ifdef DBLNET
    joe.vars = 2                  ;Modified local copy of CLS struct mys
.endc
    fred.var1 = 2                 ;Can update contents of handle
;   fred = new will.jeff()        ;Cannot create new handle
    var = "abcr"
.ifdef dblnet
    myi = 10                      ;Allowed as unspecified, will get 
                                  ; WRTLIT error in traditional
.endc
xreturn