const and #define

S

Sheldon

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
 
C

Carl B. Edwinson

Sheldon said:
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.
 
J

jameskuyper

Sheldon said:
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:
 
J

jameskuyper

[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.]
#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;
 
B

Ben Bacarisse

Sheldon said:
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.
 
M

Marston

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.

Thanks guys! It worked using sizeof! I understand now.
 
H

Hamiral

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 ;)
 
J

James Kuyper

Hamiral said:
jameskuyper a écrit :

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top