const and #define

Discussion in 'C Programming' started by Sheldon, Apr 30, 2009.

  1. Sheldon

    Sheldon Guest

    Hey!

    I have a netcdf function:

    int nc_put_vara_double(int ncid, int varid, const size_t start[],const
    size_t count[], const double *dp);

    and the following example:
    .....
    #include <netcdf.h>
    ...
    #define TIMES 3
    #define LATS 5
    #define LONS 10
    int status; /* error status */
    int ncid; /* netCDF ID */
    int rh_id; /* variable ID */
    static size_t start[] = {0, 0, 0}; /* start at first value */
    static size_t count[] = {TIMES, LATS, LONS};
    double rh_vals[TIMES*LATS*LONS]; /* array to hold values */
    int i;
    ...
    status = nc_open("foo.nc", NC_WRITE, &ncid);
    if (status != NC_NOERR) handle_error(status);
    ...
    status = nc_inq_varid (ncid, "rh", &rh_id);
    if (status != NC_NOERR) handle_error(status);
    ...
    for (i = 0; i < TIMES*LATS*LONS; i++)
    rh_vals = 0.5;
    /* write values into netCDF variable */
    status = nc_put_vara_double(ncid, rh_id, start, count, rh_vals);
    if (status != NC_NOERR) handle_error(status);
    .....

    My problem is that I cannot define the rank of the array like in the
    example. I tried solving this by doing the following:

    const size_t lev = var;
    const size_t row = var1;
    const size_t col = var2;

    and then added in the array per example: static size_t count[] = {var,
    var1, var2};

    When I compile I get the following error:
    error: initializer element is not constant

    I don't get this. Can anyone help me with this error. Would greatly
    appreciate it!

    /S
     
    Sheldon, Apr 30, 2009
    #1
    1. Advertising

  2. Sheldon wrote:
    > Hey!
    >
    > I have a netcdf function:
    >
    > int nc_put_vara_double(int ncid, int varid, const size_t start[],const
    > size_t count[], const double *dp);
    >
    > and the following example:
    > ....
    > #include <netcdf.h>
    > ...
    > #define TIMES 3
    > #define LATS 5
    > #define LONS 10
    > int status; /* error status */
    > int ncid; /* netCDF ID */
    > int rh_id; /* variable ID */
    > static size_t start[] = {0, 0, 0}; /* start at first value */
    > static size_t count[] = {TIMES, LATS, LONS};
    > double rh_vals[TIMES*LATS*LONS]; /* array to hold values */
    > int i;
    > ...
    > status = nc_open("foo.nc", NC_WRITE, &ncid);
    > if (status != NC_NOERR) handle_error(status);
    > ...
    > status = nc_inq_varid (ncid, "rh", &rh_id);
    > if (status != NC_NOERR) handle_error(status);
    > ...
    > for (i = 0; i < TIMES*LATS*LONS; i++)
    > rh_vals = 0.5;
    > /* write values into netCDF variable */
    > status = nc_put_vara_double(ncid, rh_id, start, count, rh_vals);
    > if (status != NC_NOERR) handle_error(status);
    > ....
    >
    > My problem is that I cannot define the rank of the array like in the
    > example. I tried solving this by doing the following:
    >
    > const size_t lev = var;
    > const size_t row = var1;
    > const size_t col = var2;
    >
    > and then added in the array per example: static size_t count[] = {var,
    > var1, var2};
    >
    > When I compile I get the following error:
    > error: initializer element is not constant
    >
    > I don't get this. Can anyone help me with this error. Would greatly
    > appreciate it!
    >
    > /S



    You cannot init an array with variables. Define the size of the array
    first, and set the elements manually.
     
    Carl B. Edwinson, Apr 30, 2009
    #2
    1. Advertising

  3. Sheldon

    jameskuyper Guest

    Sheldon wrote:
    > Hey!
    >
    > I have a netcdf function:
    >
    > int nc_put_vara_double(int ncid, int varid, const size_t start[],const
    > size_t count[], const double *dp);
    >
    > and the following example:
    > ....
    > #include <netcdf.h>
    > ...
    > #define TIMES 3
    > #define LATS 5
    > #define LONS 10
    > int status; /* error status */
    > int ncid; /* netCDF ID */
    > int rh_id; /* variable ID */
    > static size_t start[] = {0, 0, 0}; /* start at first value */
    > static size_t count[] = {TIMES, LATS, LONS};
    > double rh_vals[TIMES*LATS*LONS]; /* array to hold values */
    > int i;
    > ...
    > status = nc_open("foo.nc", NC_WRITE, &ncid);
    > if (status != NC_NOERR) handle_error(status);
    > ...
    > status = nc_inq_varid (ncid, "rh", &rh_id);
    > if (status != NC_NOERR) handle_error(status);
    > ...
    > for (i = 0; i < TIMES*LATS*LONS; i++)
    > rh_vals = 0.5;
    > /* write values into netCDF variable */
    > status = nc_put_vara_double(ncid, rh_id, start, count, rh_vals);
    > if (status != NC_NOERR) handle_error(status);
    > ....
    >
    > My problem is that I cannot define the rank of the array like in the
    > example. I tried solving this by doing the following:
    >
    > const size_t lev = var;
    > const size_t row = var1;
    > const size_t col = var2;
    >
    > and then added in the array per example: static size_t count[] = {var,
    > var1, var2};
    >
    > When I compile I get the following error:
    > error: initializer element is not constant


    Declaring a variable as 'const' doesn't make it a constant.

    You have several options. If 'count' didn't have static storage
    duration, then you could just use {var, var1, var2} directly. If
    'count' were not declared 'const', instead of initializing it, you
    could set it:


    > I don't get this. Can anyone help me with this error. Would greatly
    > appreciate it!
    >
    > /S
     
    jameskuyper, Apr 30, 2009
    #3
  4. Sheldon

    jameskuyper Guest

    [I hit several wrong keys in a row while I was composing this, and
    accidentally sent out an incomplete message. This is the completed
    version.]

    Sheldon wrote:
    > #define TIMES 3
    > #define LATS 5
    > #define LONS 10

    ....
    > static size_t count[] = {TIMES, LATS, LONS};

    ....
    > My problem is that I cannot define the rank of the array like in the
    > example. I tried solving this by doing the following:
    >
    > const size_t lev = var;
    > const size_t row = var1;
    > const size_t col = var2;
    >
    > and then added in the array per example: static size_t count[] = {var,
    > var1, var2};


    I presume that you actually tried

    static size_t count[] = {lev, row, col};

    otherwise there's no obvious reason for you to mention those
    variables.

    > When I compile I get the following error:
    > error: initializer element is not constant


    Because count[] has static storage duration, its initializers must be
    arithmetic constant expressions (ACE).

    Declaring a variable as 'const' doesn't make it an ACE. 6.6p8 says:
    "An arithmetic constant expression shall have arithmetic type and
    shall only have operands that are integer constants, floating
    constants, enumeration constants, character constants, and sizeof
    expressions."

    Now, 'lev' has an integer type, and has been declared 'const', so it
    might seem that it should qualify as an integer constant. However,
    that's not actually the case. The term "integer constant" is reserved
    for things like 5324 or 23352U or 0x5HEF. It doesn't include variables
    of integer type declared const (6.4.4.1).

    You have a couple of options. If 'count' didn't have static storage
    duration, then you could just use {var, var1, var2} directly. If
    'count' were not declared 'const', instead of initializing it, you
    could set it:
    count[0] = var;
    count[1] = var1;
    count[2] = var2;
     
    jameskuyper, Apr 30, 2009
    #4
  5. Sheldon <> writes:
    <snip>
    > My problem is that I cannot define the rank of the array like in the
    > example. I tried solving this by doing the following:
    >
    > const size_t lev = var;
    > const size_t row = var1;
    > const size_t col = var2;
    >
    > and then added in the array per example: static size_t count[] = {var,
    > var1, var2};
    >
    > When I compile I get the following error:
    > error: initializer element is not constant
    >
    > I don't get this. Can anyone help me with this error. Would greatly
    > appreciate it!


    In addition to the other remarks I've seen, I'd add that if you are
    happy to use C99 (and thus loose some degree of portability) you can
    use a compound literal:

    (size_t []){var, var1, var2}

    can be used as the function's parameter or you can initialise a
    pointer from this array-valued expression:

    size_t *counts = (size_t []){var, var1, var2};

    You can use const if you want here too.

    All this does is replace the need to assign the values to the elements
    of a local array.

    --
    Ben.
     
    Ben Bacarisse, Apr 30, 2009
    #5
  6. Sheldon

    Marston Guest

    On Apr 30, 6:56 pm, Ben Bacarisse <> wrote:
    > Sheldon <> writes:
    >
    > <snip>
    >
    > > My problem is that I cannot define the rank of the array like in the
    > > example. I tried solving this by doing the following:

    >
    > > const size_t lev = var;
    > > const size_t row = var1;
    > > const size_t col = var2;

    >
    > > and then added in the array per example: static size_t count[] = {var,
    > > var1, var2};

    >
    > > When I compile I get the following error:
    > >  error: initializer element is not constant

    >
    > > I don't get this. Can anyone help me with this error. Would greatly
    > > appreciate it!

    >
    > In addition to the other remarks I've seen, I'd add that if you are
    > happy to use C99 (and thus loose some degree of portability) you can
    > use a compound literal:
    >
    >   (size_t []){var, var1, var2}
    >
    > can be used as the function's parameter or you can initialise a
    > pointer from this array-valued expression:
    >
    >   size_t *counts = (size_t []){var, var1, var2};
    >
    > You can use const if you want here too.
    >
    > All this does is replace the need to assign the values to the elements
    > of a local array.
    >
    > --
    > Ben.


    Thanks guys! It worked using sizeof! I understand now.
     
    Marston, Apr 30, 2009
    #6
  7. Sheldon

    Hamiral Guest

    jameskuyper a écrit :
    > Now, 'lev' has an integer type, and has been declared 'const', so it
    > might seem that it should qualify as an integer constant. However,
    > that's not actually the case. The term "integer constant" is reserved
    > for things like 5324 or 23352U or 0x5HEF. It doesn't include variables
    > of integer type declared const (6.4.4.1).


    0x5HEF ??? In which base are you counting ? I didn't know C supported it ;)
     
    Hamiral, May 1, 2009
    #7
  8. Sheldon

    James Kuyper Guest

    Hamiral wrote:
    > jameskuyper a écrit :
    >> Now, 'lev' has an integer type, and has been declared 'const', so it
    >> might seem that it should qualify as an integer constant. However,
    >> that's not actually the case. The term "integer constant" is reserved
    >> for things like 5324 or 23352U or 0x5HEF. It doesn't include variables
    >> of integer type declared const (6.4.4.1).

    >
    > 0x5HEF ??? In which base are you counting ? I didn't know C supported it ;)


    Sorry! That was a typo - dropping the 'H' is the simplest fix.
     
    James Kuyper, May 1, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    416
    Alf P. Steinbach
    May 5, 2006
  2. ThazKool
    Replies:
    1
    Views:
    450
  3. Replies:
    11
    Views:
    1,108
  4. Javier
    Replies:
    2
    Views:
    566
    James Kanze
    Sep 4, 2007
  5. 0m
    Replies:
    26
    Views:
    1,122
    Tim Rentsch
    Nov 10, 2008
Loading...

Share This Page