Hi All,

I'd like to declare a static array in a header file. Is this possible?

I assume there is a fairly simple solution to this, but I have not been able to find documentation on the correct syntax for this.

Just to be abundantly clear, I'd like to do the equivalent of:
int array[4] = {1,2,3,4};

in a header file.

Can someone tell me what the correct syntax is?

Thanks,
Guillaume

int array[4] = {1,2,3,4}; will work, but putting objects in headers is generally a bad idea because it is easy to accidentally define the object multiple times just by including the header more than once. Inclusion guards are only a partial fix for that problem.

Can you be specific about how the code you have tried does not work?

int array[4] = {1,2,3,4}; will work, but putting objects in headers is generally a bad idea because it is easy to accidentally define the object multiple times just by including the header more than once. Inclusion guards are only a partial fix for that problem.

Can you be specific about how the code you have tried does not work?

Yes, sorry for the ambiguity. I have multiple .c scripts that refer to the same header file, as follows: #include "./my_header_file.h" Inside "my_header_file.h" I define a bunch of constants/macros that each program refers to, such as:

#define LEAPYEAR(year) ((year %4 == 0) && (((year % 100 == 0) && (year % 400 != 0)) == 0))
#define NORTH 53.125
#define SOUTH 41
#define EAST -109.75
#define WEST -125
#define NODATA -9999
#define NAMESFILEPATH "/raid/gmauger/flux_names"

I'd like to add a few arrays, e.g. something looking like: #define myARRAY[4] {1,2,3,4} ... I'm not clear on your answer above, esp regarding multiple definitions of the data... this may not be an issue because the programs I'm writing are really simple -- they are all just simple scripts that either summarize or manipulate data from a large batch of output files.

thanks again,
Guillaume

So what is the problem?

The problem is that my compiler balks at the syntax I'm using to declare an array in the header file, and I can't find any documentation on what syntax to use, or even if it's possible to declare arrays (int or floating point) in a header file.

I'm fairly new to C, so if it seems like I'm not understanding something critical -- by all means, enlighten me.

It is impossible to help you without seeing the code that your compiler balks at and the errors that are thrown. Please post all of your code, or a small self-contained subset that has the error, and post all of the errors you get.

It is impossible to help you without seeing the code that your compiler balks at and the errors that are thrown. Please post all of your code, or a small self-contained subset that has the error, and post all of the errors you get.

Got it. Sorry. Here is the header file (entitled "VIC_2860.h"):

#define NUMMONTHS 12
#define LEAPYEAR(year) ((year %4 == 0) && (((year % 100 == 0) && (year % 400 != 0)) == 0))

#define NORTH 53.125
#define SOUTH 41
#define EAST -109.75
#define WEST -125
#define LLINC .0625

#define NGRIDCELLS 24108
#define NLAT 195
#define NLON 245
#define NODATA -9999

#define NAMESFILEPATH "/raid/gmauger/data_processing/hb2860/VIC_SUMM/flux_names"
#define FLUXFLLIST "/raid/gmauger/data_processing/hb2860/VIC_SUMM/fluxfilelist_arc_pnw"
#define LATLONLIST "/raid/gmauger/data_processing/hb2860/VIC_SUMM/latlonlist_arc_pnw"

#define N_GLAC=22;
#define latGLAC[22] = {43.96875, 45.34375, 45.34375, 46.15625, 46.21875, 46.28125, 46.78125, 46.84375, 46.84375, 46.84375, 46.90625, 47.46875, 47.53125, 47.78125, 47.78125, 48.03125, 48.03125, 48.59375, 48.78125, 48.78125, 48.96875, 51.46875};
#define lonGLAC[22] = {-110.84375, -121.65625, -121.71875, -121.46875, -121.53125, -121.84375, -121.71875, -121.65625, -121.71875, -121.78125, -121.78125, -120.84375, -121.21875, -123.65625, -123.71875, -121.09375, -121.15625, -113.71875, -121.34375, -121.84375, -114.21875, -117.78125};

#define GRIDHEADER "ncols\t245\nnrows\t195\nxllcorner\t-125\nyllcorner\t41\ncellsize\t0.0625\nNODATA_value\t-9999\n"

And here is the .c script that calls it:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "./VIC_2860.h"

int main(int argc, char* argv[]) {

    char inpathstr[150], outpathstr[150];
    FILE *fileIN, *fileOUT;
    float latlondat[NGRIDCELLS][3], outROW[NLON];
    float fLAT, fLON;
    int q, i, rmGLAC;

    // Check arguments: 
    if (argc != 4) {
                puts("Wrong command line arguments: enter <summary file name> <gridinfo file name> <rmGLAC>\n");
                exit (1);
    }

    // READ ARGUMENT STRINGS:
    sscanf(argv[1],"%s",inpathstr);
    sscanf(argv[2],"%s",outpathstr);
    sscanf(argv[3],"%d",&rmGLAC);
    if ( rmGLAC == 1 ) { printf("    ***Removing glaciating cells:\n"); }

    // READ IN INPUT (MEAN-OF-SUMMARY) FILE:
    if ((fileIN = fopen(inpathstr, "r")) == NULL) {
                printf("error:  cannot open %s\n", inpathstr);
                exit(1);
    }
    q=0;
    while(fscanf(fileIN,"%f %f %f",&latlondat[q][0],&latlondat[q][1],&latlondat[q][2]) != EOF){
      //printf("%f %f %f\n",latlondat[q][0],latlondat[q][1],latlondat[q][2]);
      q++;
    }
    fclose(fileIN);
    //printf("    NGRIDCELLS = %d \n",NGRIDCELLS);
    //printf("    number of rows in input file: %d \n",q);

    // OPEN OUTPUT FILE:
    printf("    saving: %s\n",outpathstr);
    if ((fileOUT = fopen(outpathstr, "w")) == NULL) {
                printf("Can't open output file %s", outpathstr);
                exit(1);
     }
    fputs(GRIDHEADER, fileOUT);   // ADD HEADER AS FIRST LINE

    // WRITE TO GRID FILE, ONE LAT ROW AT A TIME
    for ( fLAT = NORTH+LLINC/2; fLAT >= SOUTH; (fLAT -= LLINC) ) {
        for ( fLON = WEST+LLINC/2; fLON <= EAST+LLINC/2; (fLON += LLINC) ) {

            // find 1D position of grid point
            q=0;
            while ( ( latlondat[q][0] != fLAT || latlondat[q][1] != fLON ) && q < NGRIDCELLS ) {
                q++;
            }

            // if exists, print value, else, pring NODATA
            if ( q == NGRIDCELLS && ( latlondat[q][0] != SOUTH || latlondat[q][1] != EAST ) ) {
                fprintf(fileOUT, "%d ",NODATA);
            }
            else {
                // Check for glaciated cells
                i=0;
                while ( ( fLAT != latGLAC[i] || fLON != lonGLAC[i] ) && i < N_GLAC ) {
                    i++;
                }

                // only print data if not glaciated or if not removing glaciated cells
                if ( rmGLAC == 1 && i != N_GLAC ) {
                    fprintf(fileOUT, "%d ",NODATA);
                    //printf("fluxes_%f_%f\n",latGLAC[i],lonGLAC[i]);
                }
                else {
                    fprintf(fileOUT, "%.1f ",latlondat[q][2]);
                }
            }
        }
        // print new line
        fprintf(fileOUT, "\n");

        // sanity check:
        //printf("LAT: %f, LON RANGE: %f - %f \n",fLAT,WEST+LLINC/2,fLON);

    }
    fclose(fileOUT);
}

And here are the errors I get on compiling it:

[guillaume: ~]$ gcc -o summ2grdasc summ2grdasc.c
In file included from summ2grdasc.c:13:
./VIC_2860.h:21:15: warning: ISO C requires whitespace after the macro name
./VIC_2860.h:22:16: warning: ISO C requires whitespace after the macro name
./VIC_2860.h:23:16: warning: ISO C requires whitespace after the macro name
summ2grdasc.c: In function `main':
summ2grdasc.c:81: error: syntax error before '[' token
summ2grdasc.c:81: error: syntax error before '=' token
summ2grdasc.c:86: error: syntax error before '=' token
summ2grdasc.c: At top level:
summ2grdasc.c:95: error: syntax error before '}' token
summ2grdasc.c:97: error: syntax error before string constant
summ2grdasc.c:97: error: conflicting types for 'fprintf'
summ2grdasc.c:97: note: a parameter list with an ellipsis can't match an empty parameter name list declaration
summ2grdasc.c:97: error: conflicting types for 'fprintf'
summ2grdasc.c:97: note: a parameter list with an ellipsis can't match an empty parameter name list declaration
summ2grdasc.c:97: warning: data definition has no type or storage class
summ2grdasc.c:103: warning: parameter names (without types) in function declaration
summ2grdasc.c:103: warning: data definition has no type or storage class
summ2grdasc.c:104: error: syntax error before '}' token

If I comment out the array declarations in the header file, and put them instead directly into the .c script, then the code compiles and runs w/o any problems.

Edited 7 Years Ago by gmauger: n/a

Replace this part of your header:

#define N_GLAC=22;
#define latGLAC[22] = {43.96875, 45.34375, 45.34375, 46.15625, 46.21875, 46.28125, 46.78125, 46.84375, 46.84375, 46.84375, 46.90625, 47.46875, 47.53125, 47.78125, 47.78125, 48.03125, 48.03125, 48.59375, 48.78125, 48.78125, 48.96875, 51.46875};
#define lonGLAC[22] = {-110.84375, -121.65625, -121.71875, -121.46875, -121.53125, -121.84375, -121.71875, -121.65625, -121.71875, -121.78125, -121.78125, -120.84375, -121.21875, -123.65625, -123.71875, -121.09375, -121.15625, -113.71875, -121.34375, -121.84375, -114.21875, -117.78125};

With this:

#define N_GLAC 22
double latGLAC[22] = {43.96875, 45.34375, 45.34375, 46.15625, 46.21875, 46.28125, 46.78125, 46.84375, 46.84375, 46.84375, 46.90625, 47.46875, 47.53125, 47.78125, 47.78125, 48.03125, 48.03125, 48.59375, 48.78125, 48.78125, 48.96875, 51.46875};
double lonGLAC[22] = {-110.84375, -121.65625, -121.71875, -121.46875, -121.53125, -121.84375, -121.71875, -121.65625, -121.71875, -121.78125, -121.78125, -120.84375, -121.21875, -123.65625, -123.71875, -121.09375, -121.15625, -113.71875, -121.34375, -121.84375, -114.21875, -117.78125};

There were two problems. First is you were defining N_GLAC the wrong way for a macro. Macros do not use the = sign to assign a value, and they do not end with a semicolon. Second, you were trying to define arrays with macro syntax. A header is nothing special when it comes to defining objects. You do it the same way as any global variable.

This question has already been answered. Start a new discussion instead.