Re: [netcdfgroup] offsets are ignored when creating compound types

Hi Felipe,

> I have found out that NetCDF-4 ignores the offsets that the users specifies
> when creating compound types. Instead, I think it calculates the offsets
> taking into account the architecture alignment rules.
>
> So it is not possible for example to create a compound offset without
> defining a "struct" in your C program. My problem is that I need to write a
> program that is able to create arbitrary compound objects.

It *is* possible to create a compound offset without defining a struct
in your C program.  For example, ncgen uses CDL input describing a
compound type to generate a corresponding netCDF file at run time,
without a corresponding struct.  Also the new nccopy utility uses only
the netCDF C API to structurally copy netCDF files, so when it copies a
netCDF-4 file with a compound type, it must create the necessary type in
the target file without having a corresponding C struct.

As an example, consider the following CDL file, fb.cdl:

  netcdf fb {
  types:
    compound mystruct_t {
      byte field1;
      int field2;
      float field3;
    }; // mystruct_t
  variables:
    mystruct_t cvar;
  data:
    cvar = {123, 0, 45.67};
  }

If you use the ncgen in the current snapshot release (previously named
ncgen4 in the 4.0.1 release), it creates the corresponding netCDF file,
as ncdump verifies:

  $ ncgen -k 3 -b fb.cdl
  $ ncdump fb.nc
  netcdf fb {
  types:
    compound mystruct_t {
      byte field1 ;
      int field2 ;
      float field3 ;
    }; // mystruct_t
  variables:
          mystruct_t cvar ;
  data:

   cvar = {123, 0, 45.67} ;
  }

Furthermore, you can use ncgen to generate a corresponding C program,
compile and run it, and you will still get the same netCDF file.  The
generated C program does use a C struct for simplicity.

  $ ncgen -k 3 -lc fb.cdl > fb.c
  $ cc `nc-config --cflags` fb.c -o fb `nc-config --libs`
  $ ./fb
  $ ncdump fb.nc
  [ ... same result as above]

> Another thing that is not possible is to create a compound type that is an
> extract (a subset) of a larger struct. In the following simplified example,
> I have a struct with 3 fields, but I want to write to disk only the 1st and
> the 3rd fields:
> 
> ////////////////////////////
> 
> struct mystruct {
>     char field1;
>     int field2;
>     float field3;
> };
> struct mystruct myvar;
> myvar.field1=123;
> myvar.field3=45.67;
> 
> nc_def_compound(ncid, sizeof(struct mystruct), "MYSTRUCTEXTRACT", &typeid);
> nc_insert_compound(ncid, typeid, "FIELD1", 0, NC_BYTE)==0);
> nc_insert_compound(ncid, typeid, "FIELD3", NC_COMPOUND_OFFSET(struct
> mystruct, field3), NC_FLOAT);
> 
> nc_def_var(ncid, "CVAR", typeid, 0, NULL, &varid);
> nc_put_var(ncid, varid, &myvar);
> 
> ////////////////////////////
> 
> The file that I create does not contain the right value for "FIELD3", and I
> think the reason is that the library is ignoring the offset that I am
> supplying.

If you edit the generated C program, fb.c, and comment out the line
inserting the "field2" member, it still works, and when run shows a
compound type with only the first and third field and the correct value
for the field3 member:

  netcdf fb {
  types:
    compound mystruct_t {
      byte field1 ;
      float field3 ;
    }; // mystruct_t
  variables:
          mystruct_t cvar ;
  data:

   cvar = {123, 45.67} ;
  }

It's possible that the different results you are seeing are from bugs in
an earlier version or indicate a new platform-specific bug we haven't
seen, but we can't reproduce the problem here.

--Russ



  • 2009 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: