Jeff Hill wrote:
The set of well defined types is:
Defining another size locked type space enum is not enough of course. You
will also need to define another set of typedefs with corresponding names.
Or anyways that is the typical approach. This was used for example with the
CA interfaces in R3.13 and R3.14 - i.e. DBR_DOUBLE corresponds to
dbr_double_t.
However, as I have mentioned before, my experience has been that programmers
become complacent - allowing their applications to become 32 bit
architecture dependent. They use the type code but generally neglect to use
the corresponding typedef - they learn that dbr_double_t is generally always
a C type "double" (on 32 bit systems), and so they just use "double". That's
what I observed with typical CA client applications. Use of interface
designs with "void *" pointers does not allow the compiler to detect such
inconsistencies.
I think the reason people did not use db_access.h definitions is
because it is quite complicated and there is no documentation except
comments in the header file
We all know by now that DA takes a different approach. DA knows the C data
type interfaced by the user and range checks / converts accordingly. The DA
design rationale is that the first priority is to know exactly what data
type the user might be actually using so that problems can be detected
during conversion.
At our SLAC meeting I mentioned that I felt that DA was lacking in
capabilities allowing the client application to learn the native type used
in the server for each property. At the recent ANL meeting I showed some
example code demonstrating an upgrade for DA allowing a sophisticated client
to learn the native type (see below for those who were not at the ANL
meeting). An important feature of this design is that there would be three
types of property catalogs; one for read/write access, one for read access,
and one for learning only the native type (in the absence of an instance of
the data). This organization, and some support templates, allows the user to
write the traverse and find functions only once, but use them in all three
of the situations described above (see below).
And the example was very complicated and what it delivered left
something to be desired.
Only a C++ Guru would appreciate the example.
Most CA client applications in use today use type double for analog values
and assume that the IOC will not produce anything larger. We appear to live
quite comfortably within the range of a 64 bit floating point types. For
practical reasons, my guess is that as 128 bit floats start to be more
commonly available they will be used initially for their improved precision
and not so much for their additional range. I am also guessing that CPUs
supporting 128 bit floats in hardware will be introduced first at the client
side. As 64 bit architectures become commonplace, 32 bit compilers will
probably routinely support software implementations of 128 bit floats
accessed via type "long double". This will allow well written 32 bit clients
to interact predictably with 64 bit servers - they can switch to type "long
double" should the server specify via the network protocol that the native
type is a 128 bit float. On a 64 bit architectures less energetic
programmers will probably eventually use 128 bit floats for all analog
values.
What if the server has a native type that is too large to be expressed as a
C type with the compiler used to compile the client? Telling them that it is
a nadTypeFloat128 isn't going to make that situation better. What *will*
help is to allow them to continue using the largest possible floating point
variable but detect during assignment all numbers that are not expressible
in their choice of variable. Many, if not most of the numbers involved will
not be out of range. Well written clients will respond appropriately when an
out of range indication is received.
What if we would like to write a client application that will use the same
native type as the server? DA interfaced clients have no problems with that
situation because it will be easy to write a DA interfaced component that
traverses the propertyCatalog and creates (in a type differentiated
callback) an instance of a template supplying for the template argument a
type functionally identical (i.e. size locked identical) to the type used in
the server. In languages w/o templates we simply call a different factory
method for each type that is needed from the type differentiated callback.
Templates makes this type of code where the type varies, but the algorithm
doesn't quite easy to write and maintain. Programmers will also probably
quickly arrive at the conclusion that it is only necessary to inflate
templates for the promoted types (as was the conclusion when implementing
the DA support libraries). Promoting to larger types might appear initially
to some to be intrusive, but when one looks at what occurs under the hood in
the compiler it can be discovered that implicit promotion is already quite
commonplace in C and C++ object code.
Your argument seems to be that as support for 128 bit ints and floats
appears then magically thibgs will continue to interoperate. This is too
good to be true.
For network data well defined types should be supported and known by any
code that accesses or provides network available data.
Finally, despite superior alternatives mentioned in the previous paragraph,
some users will insist on a data type code such as NadType (presumably for
use in a "C" myopic type code indexed jump table or switch statement). A
proliferation of such type code spaces is inevitable. Nevertheless, it will
be trivial to provide DataAccess support library components mapping to any
one of a number of type spaces. Will such support codes be sensitive to
architecture (as decided by the compiler)? You bet. So are all such mappings
such as "dbr_double_t" to "double". However, in practice we discover that
there are not that many mappings. Currently, with 32 bit systems we have
only one (one for each type code space that is).
And you will make the user do the following!!!
PropertyId propertyX;
PropertyId propertyY;
PropertyId propertyZ;
PropertyId propertyI;
struct MyContainer
{
public:
MyContainer ();
PropertyManipulator::catalog_t & makeManipulator ();
PropertyViewer::catalog_t & makeViewer () const;
static PropertySurveyor::catalog_t & makeSurveyor ();
private:
int x;
float y;
double z;
char i;
template < class VIEWER >
static void traverse ( VIEWER & );
template < class VIEWER >
static bool find ( const PropertyId &, VIEWER & );
};
MyContainer::MyContainer ()
{
}
inline PropertyManipulator::catalog_t & MyContainer::makeManipulator ()
{
return * new ClassCatalog < MyContainer, PropertyManipulator, traverse,
find > ( *this );
}
inline PropertyViewer::catalog_t & MyContainer::makeViewer () const
{
return * new ClassCatalog < MyContainer, PropertyViewer, traverse, find
( *this );
}
inline PropertySurveyor::catalog_t & MyContainer::makeSurveyor ()
{
return * new ClassCatalog < MyContainer, PropertySurveyor, traverse,
find > ();
}
template < class VIEWER >
inline void MyContainer :: traverse ( VIEWER & viewer )
{
viewer.reveal ( propertyX, & MyContainer::x );
viewer.reveal ( propertyY, & MyContainer::y );
viewer.reveal ( propertyZ, & MyContainer::z );
viewer.reveal ( propertyI, & MyContainer::i );
}
template < class VIEWER >
inline bool MyContainer::find ( const PropertyId & id, VIEWER & viewer )
{
bool status = true;
if ( id == propertyX ) {
viewer.reveal ( propertyX, & MyContainer::x );
}
else if ( id == propertyY ) {
viewer.reveal ( propertyY, & MyContainer::y );
}
else if ( id == propertyZ ) {
viewer.reveal ( propertyY, & MyContainer::z );
}
else if ( id == propertyI ) {
viewer.reveal ( propertyY, & MyContainer::i );
}
else {
status = false;
}
return status;
}
void fred ()
{
MyContainer mc;
PropertyManipulator::catalog_t & catM = mc.makeManipulator ();
PropertyViewer::catalog_t & catI = mc.makeViewer ();
PropertySurveyor::catalog_t & catS = MyContainer::makeSurveyor ();
}
- Replies:
- Re: Network Accessable Types Andrew Johnson
- References:
- RE: Network Accessable Types Jeff Hill
- Navigate by Date:
- Prev:
Re: Standard String Benjamin Franksen
- Next:
Re: Network Accessable Types Andrew Johnson
- Index:
2002
2003
2004
<2005>
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: Network Accessable Types Jeff Hill
- Next:
Re: Network Accessable Types Andrew Johnson
- Index:
2002
2003
2004
<2005>
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|