EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Record support and user-defined fields
From: Marty Kraimer <[email protected]>
To: [email protected]
Date: Wed, 13 Jul 2005 06:49:53 -0500


Benjamin Franksen wrote:

On Tuesday 12 July 2005 15:43, Marty Kraimer wrote:
The following can be defined:

menu(invalidAction) {
   choice(invalidActionContinue_normally,"Continue normally")
   choice(invalidActionDon_t_drive_outputs,"Don't drive outputs")
   choice(invalidActionSet_output_to_IVOV,"Set output to IVOV")
}

struct(invalidOutput, type {
    field(invalidAction,menu(menuIvoa))
    field(invalidValue,Value)
}

And  then the record.dbd would be


   field(invalidOutput,struct(invalidOutput,float64))
   field(output,device(none,processInvalidOutput))

Fine. Do we agree that we may need more than one type parameter in struct definitions? (Although it will probably not be very common). The following should be allowed (for n >= 0):

 struct(structName, type_var_1, type_var_2, ..., type_var_n) {
     ...
 }

and then in a record type definition

 field(fieldName,struct(structName, type_1, ..., type_n))

Andrew,

Does this present problems?

And the interface definittion becomes

Some .h file contains:

   class processInvalidOutput {
        virtual void compute(invalidOutput<epicsInt32>
&output,,epicsString &status, epicsInt16 &severity);
         virtual void compute(invalidOutput<epicsInt32>
&output,,epicsString &status, epicsInt16 &severity);
         ... // perhaps other types for value
   }

Assuming you meant to write 'invalidOutput<epicsFloat64>' in one of the two methods above, this still falls short of a real templatized version:

 class processInvalidOutput {
     template <typename ValueType>
void compute(invalidOutput<ValueType>&output, epicsString &status, epicsInt16 &severity);
 }

Yes it does but it is what I think users should see.

This

The interface has overloaded methods for the types that are implemented.

The implementation can use templates so that the algoritm is only implemented once.
The interface shows what types are implemented.

One must be very careful in C++ with overloading. If in the above example you forget to declare a method for invalidOutput<epicsInt16>, the argument will silently be converted/promoted to the next larger numeric type, like in C. This might be compiler dependent.

But the is no different that any other method or function call.

I have no idea what happens if the reference is used to overwrite the value field; maybe the compiler disallows it but then generality suffers, i.e. you cannot use the struct/template/device-whatever for numeric types other than the ones you provide definitions for.

Templatizing the method leads to more predictable behavior (no conversions). However, it also has some disadvantages:

o Compiler error messages can become somewhat lengthy and obscure.
 OTOH, I rather get a confusing and hard to decipher error message
 from the compiler than strange behavior at run-time.
o More serious: it depends on the implementation of the (templatized)
 method, which types are actually allowed in instances. For instance,
 if a '<' operator is used on the value, compilation will fail if
 instantiated with a type that has no operator '<' defined.

I am uncertain how much of a problem the latter problem is going to be in practice. If someone wants to instantiate such a template for an unexpected type and the compiler complains, the record type designer is free to provide the expected operations (for instance, an operator '<'). If that is impossible or just impractical, the instantiation probably doesn't make sense anyway. I still don't like it, because it means I must take back my claim that I can give a C==-independent self-contained definition of what type parameters in the DBD file mean.

Hmmm.

Sounds like you agree with that that presenting full blown templates to users is not very nice :-)


Marty

and the process method calls

pprocessInvalidOutput->compute(invalidOutput,status,severity);

Ben



Replies:
Re: Record support and user-defined fields Benjamin Franksen
References:
V4 iocRecord: forward linking Ralph Lange
Re: Record support and user-defined fields Benjamin Franksen
Re: Record support and user-defined fields Marty Kraimer
Re: Record support and user-defined fields Benjamin Franksen

Navigate by Date:
Prev: Re: V4 Design: Record Processing Marty Kraimer
Next: RE: V4 Design: Record Processing Liyu, Andrei
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Record support and user-defined fields Benjamin Franksen
Next: Re: Record support and user-defined fields Benjamin Franksen
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·