Implied data conversion (casting) of non-class code

Posted by jmartin104 on 04-Dec-2018 20:27

I can't seem to locate it, but I'm assuming OpenEdge allows implied data conversion. Is this documented? For example, the code below does not generate an error or warning.

According to online documentation "The parameters specified by parameter must match in number and order, according to mode and data type, as required by the given procedure..."

"The AVM implicitly converts passed parameter values of certain data types from a narrow data type in the source to a widened data type in the destination, depending on the parameter mode. A widened data type is one that can hold all the values of a narrower data type without loss of data. Widening is supported for three related sets of data types, as shown in the following table, where the arrow ( —>) indicates the direction that a value can be passed for the parameter."

- (Parameter Passing Syntax)

However, the table does not seem to indicate anything other than a longchar as valid for a char.

def var myInt as int no-undo init 7.

run myProc(myInt).

procedure myProc:
    define input param myChar as char no-undo.
    disp myChar.
end.

All Replies

Posted by Laura Stern on 04-Dec-2018 20:48

For better or worse, there are 2 sets of rules regarding data conversion.  In the procedural and assignment world, the AVM is much looser about data type conversions.  I would say almost anything is allowed that can be.  So you can pass an INT to a CHAR and it will be converted as if you had used the STRING() function on the number.  Similar conversions are done for assignments. You can even pass an INT64 to an INT as long as the value at run-time is not too big to fit.  I don't know if this is documented anywhere.  I thought it was in the old programming handbook, but that is long gone.  

However, in the OO world, we are much stricter about what is compatible with what.  You can pass an INT to an INT64, or a CHAR to a LONGCHAR, but for each, not the other way around.  The compiler enforces this, not the run-time.  And you cannot pass an INT to a CHAR, etc.  I thought this set of rules was documented in the OO book but honestly, I cannot find it right now.

Posted by Patrick Tingen on 05-Dec-2018 08:56

As an addition: the loosely way the AVM handles for PROCEDURES does not apply to functions. The example below will not work:

FUNCTION test RETURNS LOGICAL
  ( pcParam AS CHARACTER ):
  MESSAGE pcParam VIEW-AS ALERT-BOX INFO BUTTONS OK.
END FUNCTION. 

test(123).

Posted by 2087 on 05-Dec-2018 09:07

As Patrick has pointed out this does not apply to FUNCTIONS - which in my opinion is one very good reason to always use FUNCTIONS in preference to PROCEDUREs. A second reason is that incorrect parameters to a FUNCTION is a compile time error, whereas incorrect parameters to a PROCEDURE is run-time error. This doesn't answer your question, but if you avoid the use of PROCEDURE then you can avoid the whole type conversion in the first place.

Posted by jmartin104 on 05-Dec-2018 11:58

This was something a colleague stumbled upon and shared with our team. I'm not a fan of implicit casting and never thought OpenEdge would entertain it - I've always been explicit with my data types. I did find it interesting; having developed with Progress for over 20 years, I've found it (Progress) to be full of quirks, nuances and undocumented features but I've never come across this one.

Posted by 2087 on 05-Dec-2018 12:14

It's something I have used a few times but it was never intentional - only by mistake. I too am no a fan of this feature.

Posted by gus bjorklund on 06-Dec-2018 21:42

> On Dec 5, 2018, at 6:59 AM, jmartin104 wrote:

>

> having developed with Progress for over 20 years, I've found it (Progress) to be full of quirks, nuances and undocumented features

Most programming languages are infested with such things.

This thread is closed