Originally reported via esupport ticket XKJ-645277
When I call nc_get_vara_double() to read floats from a dataset I get
zeros rather than the values in the dataset.
I tracked it down to a typecast in the function swap4b() in
libsrc/ncx.m4:205 Here's the line of code:
*(float *)op = *(float *)(&tempOut);
This does type punning, accessing an unsigned value (tempOut) via a cast
to a float*, which the C standard says results in undefined behavior.
When I compile with GCC's -Wall, the compiler points out the bug in the
source:
ncx.m4:205: warning: dereferencing type-punned pointer will break strict-aliasing rules
There are also four lines in ncdump/ncdump.c that cause the same warning.
I can work around the problem by building the output of libsrc/ncx.m4
with the GCC option -fno-strict-aliasing. Compiled with no special
options, the function ends like this and results in zeros:
mov -0x4(%rsp),%eax
or %edx,%ecx
mov %ecx,-0x4(%rsp)
mov %eax,(%rdi)
retq
Complied with -fno-strict-aliasing, it ends like this and works:
or %edx,%ecx
mov %ecx,-0x4(%rsp)
mov -0x4(%rsp),%eax
mov %eax,(%rdi)
retq
I'm building netCDF 4.4.1 with GCC 4.9.2 for Linux.
Originally reported via esupport ticket
XKJ-645277When I call
nc_get_vara_double()to read floats from a dataset I getzeros rather than the values in the dataset.
I tracked it down to a typecast in the function
swap4b()inlibsrc/ncx.m4:205Here's the line of code:This does type punning, accessing an unsigned value (tempOut) via a cast
to a float*, which the C standard says results in undefined behavior.
When I compile with GCC's
-Wall, the compiler points out the bug in thesource:
There are also four lines in
ncdump/ncdump.cthat cause the same warning.I can work around the problem by building the output of libsrc/ncx.m4
with the GCC option
-fno-strict-aliasing. Compiled with no specialoptions, the function ends like this and results in zeros:
mov -0x4(%rsp),%eax
or %edx,%ecx
mov %ecx,-0x4(%rsp)
mov %eax,(%rdi)
retq
Complied with -fno-strict-aliasing, it ends like this and works:
or %edx,%ecx
mov %ecx,-0x4(%rsp)
mov -0x4(%rsp),%eax
mov %eax,(%rdi)
retq
I'm building netCDF 4.4.1 with GCC 4.9.2 for Linux.