This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
>To: address@hidden >From: address@hidden >Subject: BOUNCE address@hidden: Non-member submission from [Philippe Poilbarbe <address@hidden>] >Organization: UCAR/Unidata >Keywords: 200403120804.i2C840hS019881 Hi Philippe, > Here is a bug found in ncdump utility delivered with netCDF V3.5.0. > > The bug appears when attributes have a zero length. In this case, it > tries to show them as 0 length string but the way it is implemented > is buggy. The value shown depends on the non empty preceding > attribute. If it is a string, the first letter of this string is > repeated as the value of all empty following attributes (due to a > reuse of allocated data not initialized) > > Below is an exemple (the last 3 attributes have 0 values): > > :Data_provider = "Data provider" ; > :Experiment_name = "D" ; > :Project_name = "D" ; > :Experiment_description = "D" ; > > You can find joined a patch which can be used to correct this > problem and another (incorrect writing of control characters). Thanks for reporting this and providing a patch. It may be already fixed in netCDF 3.5.1, because I cannot reproduce the problem. I have attached a test program that creates several variable and global attributes with 0 values, but the output of ncdump on the resulting netCDF file has all of these displayed as an empty string on my Solaris SPARC platform. If you still see the bug using this test program, could you tell me what operating system and platform you are using? Or send me a complete program that demonstrates the problem? Thanks! > On an another way here is a question: does it take any sense to have > an attribute with no value ? IMHO, if there is no value the attribute has > not to be created. We explicitly permit attributes to be defined with no value, because we want to provide a way to declare that a variable has a particular characteristic, for example whether it is georeferenced (associated with a latitude/longitude location on earth). The characteristic has a name, and the variable either has the characteristic or doesn't, so a Boolean attribute might be used, as in: georeferenced = True or georeferenced = False But it seems more elegant to just attach the attribute, without values, to variables for which the characteristic is true, and variables for which the characteristic is false or does not apply do not have the attribute. This is analogous to the use of C preprocessor macros, which may have a value, but are often used just to test whether they are defined or not, without regard for any value. For example, if you include -DHAS_PROPERTY_X on your compile line, it defines the macro "HAS_PROPERTY_X" without a value, and it can be tested by the C preprocessor using #ifdef HAS_PROPERTY_X --Russ
netcdf bug5 { variables: int x ; x:Data_provider = "Data provider" ; x:HasProperty = "" ; x:Experiment_name = "" ; x:Project_name = "" ; x:Experiment_description = "" ; // global attributes: :History = "Generated for testing" ; :HasProperty = "" ; :source = "" ; :provinence = "" ; data: x = 0 ; }
#include <stdio.h> #include <stdlib.h> #include <netcdf.h> void check_err(const int stat, const int line, const char *file) { if (stat != NC_NOERR) { (void) fprintf(stderr, "line %d of %s: %s\n", line, file, nc_strerror(stat)); exit(1); } } int main() { /* create bug5.nc */ int ncid; /* netCDF id */ /* variable ids */ int x_id; /* rank (number of dimensions) for each variable */ # define RANK_x 0 /* enter define mode */ int stat = nc_create("bug5.nc", NC_CLOBBER, &ncid); check_err(stat,__LINE__,__FILE__); /* define variables */ stat = nc_def_var(ncid, "x", NC_INT, RANK_x, 0, &x_id); check_err(stat,__LINE__,__FILE__); /* assign attributes */ stat = nc_put_att_text(ncid, x_id, "Data_provider", 13, "Data provider"); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_int(ncid, x_id, "HasProperty", NC_INT, 0, (void *)0); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_text(ncid, x_id, "Experiment_name", 0, ""); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_text(ncid, x_id, "Project_name", 0, ""); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_text(ncid, x_id, "Experiment_description", 0, ""); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_text(ncid, NC_GLOBAL, "History", 21, "Generated for testing"); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_int(ncid, NC_GLOBAL, "HasProperty", NC_INT, 0, (void *)0); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_text(ncid, NC_GLOBAL, "source", 0, ""); check_err(stat,__LINE__,__FILE__); stat = nc_put_att_text(ncid, NC_GLOBAL, "provinence", 0, ""); check_err(stat,__LINE__,__FILE__); /* leave define mode */ stat = nc_enddef (ncid); check_err(stat,__LINE__,__FILE__); { /* store x */ static int x = 0; stat = nc_put_var_int(ncid, x_id, &x); check_err(stat,__LINE__,__FILE__); } stat = nc_close(ncid); check_err(stat,__LINE__,__FILE__); return 0; }