Closed dirk-zimoch closed 4 years ago
This does look strange. It's been 4 years since I added this, and I must admit that I'm having trouble remembering the details. The situation I faced at the time involved a custom device with real ieee floating point registers.
For a device with real floating point registers the code won't work. The registers are always read as integers and stored in epicsUInt32 OV
. Casting them to float is of course not the same as reading them as float. That would require a readraw
(or read
) version which uses for example a union to reinterpret the value as float.
There is a union hiding in the castval<>
template. So it does work, at least on Linux. I'm working on adding a test case to demonstrate this.
Of course, I must acknowledge that there are unnecessary casts happening, and that the appearance of correctness may well depend on how GCC optimizes these casts. There is room for improvement.
Oops. I missed that. Sorry.
I may have addressed this with 614e0a8dfd1c061135d9c64627b58ccfdbf80c00. Do you still see this warning? If so, which warning is it? It would help for me to know what to look for in eg. the appveyor output.
I used to get the warnings from the Microsoft compiler (in both, 32 bit and 64 build). It is very sensitive to potential data loss due to implicit casting, e.g. 32 bit integer to 32 bit float.
/opt/wine-msvc-2017/bin/x86/cl -EHsc -GR -DUSE_TYPED_RSET -I../../../common -nologo -FC -D__STDC__=0 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -Ox -GL -Oy- -W3 -w44355 -w44344 -w44251 -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING -MD -DEPICS_BUILD_DLL -DEPICS_CALL_DLL -TP -I. -I../O.Common -I. -I. -I.. -I../../../include/compiler/msvc -I../../../include/os/WIN32 -I../../../include -I/usr/local/epics/base-7.0.4.1/include/compiler/msvc -I/usr/local/epics/base-7.0.4.1/include/os/WIN32 -I/usr/local/epics/base-7.0.4.1/include -c ../devexplore.cpp
devexplore.cpp
z:\afs\psi.ch\group\8211\dirk\git\devlib2\exploreapp\src\devexplore.cpp(154): warning C4244: 'initializing': conversion from 'VAL' to 'epicsUInt32', possible loss of data
with
[
VAL=epicsFloat32
]
z:\afs\psi.ch\group\8211\dirk\git\devlib2\exploreapp\src\devexplore.cpp(475): note: see reference to function template instantiation 'unsigned int `anonymous-namespace'::priv::readArray<epicsFloat32>(VAL *,unsigned int) const' being compiled
with
[
VAL=epicsFloat32
]
z:\afs\psi.ch\group\8211\dirk\git\devlib2\exploreapp\src\devexplore.cpp(143): warning C4244: 'return': conversion from 'epicsUInt32' to 'VAL', possible loss of data
with
[
VAL=epicsFloat32
]
z:\afs\psi.ch\group\8211\dirk\git\devlib2\exploreapp\src\devexplore.cpp(154): note: see reference to function template instantiation 'VAL `anonymous-namespace'::priv::read<VAL>(epicsUInt32) const' being compiled
with
[
VAL=epicsFloat32
]
z:\afs\psi.ch\group\8211\dirk\git\devlib2\exploreapp\src\devexplore.cpp(475): note: see reference to function template instantiation 'unsigned int `anonymous-namespace'::priv::readArray<epicsFloat32>(VAL *,unsigned int) const' being compiled
with
[
VAL=epicsFloat32
]
I had as well seen this warning from g++ 3.4.3
../devexplore.cpp: In member function `epicsUInt32 <unnamed>::priv::readraw(epicsUInt32) const':
../devexplore.cpp:118: warning: converting of negative value `-0x00000000000000001' to `epicsUInt32'
../devexplore.cpp: In member function `unsigned int <unnamed>::priv::readArray(VAL*, unsigned int) const [with VAL = epicsFloat32]':
../devexplore.cpp:475: instantiated from here
../devexplore.cpp:154: warning: converting to `epicsUInt32' from `epicsFloat32'
Both are gone now
When instatiated with epicsFloat32 in line 155, strange conversions are going on (and some compilers warn)
read<VAL>
returns epicsFloat32 which is then cast to epicsUInt32, then back to epicsFloat32.Also, in template read VAL is copied but not cast to a epicsUInt32, which generates a warning for VAL=epicsFloat32.
I find all this casting between epicsUInt32 and epicsFloat32 across 3 templates quite questionable.
As
readraw
reads epicsUInt32 and then casts to VAL, there is no reason for read to callreadraw<VAL>
. It should callreadraw<epicsUInt32>
. For the same reason, readArray should callread<epicsUInt32>
instead ofread<VAL>
.