netcdf-c: Incorrect fill value being used for enums (was: ncdump failure on enum file: dumplib.c; line 952)

I found this while writing some tests for parallel. But it also happens in non-parallel mode. This happens on current master.

I have added a test to nc_test4/tst_enum.c which creates a very simple file with one enum variable. Then one value is written.

Here’s the test code:

#define ENUM_NAME "cargo"
#define ENUM_VAR_NAME "in_the_hold_of_the_Irish_Rover"
#define NUM_ENUM_FIELDS 8
#define DIMSIZE 4
#define NDIMS1 1
   {
      int ncid, dimid, v1id, typeid;
      int f;
      size_t start[NDIMS1] = {0}, count[NDIMS1] = {1};
      char field_name[NUM_ENUM_FIELDS][NC_MAX_NAME + 1] = {"bags of the best Sligo rags", "barrels of bones",
                                                           "bails of old nanny goats' tails", "barrels of stones",
                                                           "dogs", "hogs", "barrels of porter",
                                                           "sides of old blind horses hides"};
      unsigned long long field_value[NUM_ENUM_FIELDS] = {1000000, 2000000, 3000000, 4000000,
                                                         5000000, 6000000, 7000000, 8000000};
      unsigned long long data = 1000000, data_in;
      
      /* Create a netcdf-4 file. */
      /*nc_set_log_level(3);*/
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      
      /* Create a dimension. */
      if (nc_def_dim(ncid, DIM_NAME, DIMSIZE, &dimid)) ERR;
      
      /* Create an enum type. */
      if (nc_def_enum(ncid, NC_UINT64, ENUM_NAME, &typeid)) ERR;
      for (f = 0; f < NUM_ENUM_FIELDS; f++)
         if (nc_insert_enum(ncid, typeid, field_name[f], &field_value[f])) ERR;
      
      /* Create one var. */
      if (nc_def_var(ncid, ENUM_VAR_NAME, typeid, NDIMS1, &dimid, &v1id)) ERR;
      
      /* Write metadata to file. */
      if (nc_enddef(ncid)) ERR;
      
      /* Write phoney data. */
      if (nc_put_vara(ncid, v1id, start, count, &data)) ERR;
      
      if (nc_sync(ncid)) ERR;

      /* Read phoney data. */
      if (nc_get_vara(ncid, v1id, start, count, &data_in)) ERR;
      if (data_in != data) ERR;
      
      /* Close the netcdf file. */
      if (nc_close(ncid)) ERR;
   }

The test succeeds without problem. But when ncdumping the resulting file I get:

netcdf tst_enums {
types:
  uint64 enum cargo {bags\ of\ the\ best\ Sligo\ rags = 1000000, 
      barrels\ of\ bones = 2000000, 
      bails\ of\ old\ nanny\ goats\'\ tails = 3000000, 
      barrels\ of\ stones = 4000000, dogs = 5000000, hogs = 6000000, 
      barrels\ of\ porter = 7000000, 
      sides\ of\ old\ blind\ horses\ hides = 8000000} ;
dimensions:
	dim = 4 ;
variables:
	cargo in_the_hold_of_the_Irish_Rover(dim) ;
data:

NetCDF: Invalid argument
Location: file dumplib.c; line 952
 in_the_hold_of_the_Irish_Rover = bags of the best Sligo rags, 

(Could this be related to the spaces in the enum field names? Or could it be when it is trying to print the default fill value? Because I only write one data element to the array, leaving the rest as fill value. And it is in printing the fist fill value that ncdump fails.)

This code is in nc_test4/tst_enums.c in my currently open PR #979. I have also added a test to the ncdump directory by adding this netCDF file as ref_tst_irish_rover.nc and then added a line (currently commented out) to tst_netcdf4.sh:

echo "*** creating tst_output_irish_rover.cdl from ref_tst_irish_rover.nc..."
#${NCDUMP} ref_tst_irish_rover.nc > tst_output_irish_rover.cdl

This currently fails, since ncdump returns 1 when it encounters this problem.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Comments: 29 (10 by maintainers)

Commits related to this issue

Most upvoted comments

I have a fix PR. Using a variant of Ed’s test case (where the variable data is all zero except the first element). ncdump now produces the output below. Is this acceptable solution?

netcdf t {
types:
  uint64 enum cargo {bags\ of\ the\ best\ Sligo\ rags = 1000000, 
      barrels\ of\ bones = 2000000, 
      bails\ of\ old\ nanny\ goats\'\ tails = 3000000, 
      barrels\ of\ stones = 4000000, dogs = 5000000, hogs = 6000000, 
      barrels\ of\ porter = 7000000, 
      sides\ of\ old\ blind\ horses\ hides = 8000000} ;
dimensions:
	dim = 4 ;
variables:
	cargo in_the_hold_of_the_Irish_Rover(dim) ;
data:

 in_the_hold_of_the_Irish_Rover = bags of the best Sligo rags, _UNDEFINED, 
    _UNDEFINED, _UNDEFINED ;
}

This slipped thru the cracks, sorry.