Search code examples
c++embeddedkeil

static variables in switch statements


I am working on a keil project using c. In one of my files, I have defined some variables at the top as static. I use them in some functions in this file and I also use them in a switch/case statement. For example:

at the top where variables are defined:

static uint8_t* imageData = 0;
static uint32_t height = 0;
static uint32_t width = 0;
static uint32_t stride = 0;

in the middle of the code:

switch (pMsg->MsgId)
{

case WM_CREATE:
{     
    CAMERA_Init();   
    AMProcessor *processor = new AMProcessor();

    struct block blocks[2] = {
                                 {2, 240, 160},
                                 {2, 160, 120}                              
                            };
    processor->initBlocks(blocks, 2);           
    stride = 480; //sample_image.width;                                 
    processor->Initialize(480, 272, 480, InputTypes::CHROMA_MOBILE, InputTypes::RGB); 
    BSP_LED_Toggle(LED3);

    while(1){                               
        const PictureOutput* picOut = processor->ProcessImage((uint8_t *)CAMERA_FRAME_BUFFER);                              
        break;
    }
}

and near the bottom I have a couple of functions that also use these variables. However, I am getting warnings that are telling me that the 4 variables defined at the top are initialized but never referenced. If they are not static then I do not get this warning, but I get a hard fault error (which I am trying to get rid of).

So my question is, why are these not referenced? It obviously has something to do with the static definition, but how come the static definition wouldn´t allow these to be referenced?

for clarification: I am getting this message on all of them, even stride. warning: #177-D: variable "imageData" was declared but never referenced

I have a function at the bottom that uses all of these variables that looks like this:

bool ReadImageFromPgmFile(const char* pFileName, uint32_t &height, uint32_t &width, uint8_t*& ImgData) {
    if (pFileName == 0) {
            return false;
    };

    // read data from file
    if (strstr(pFileName, ".pgm") || strstr(pFileName, ".PGM")) {
            FILE *pPgmFile = fopen(pFileName, "r");

            if (pPgmFile == NULL) {
                    fprintf(stderr, "Cannot open PGM file '%s'.\n", pFileName);
                    return false;
            };

            char x = fgetc(pPgmFile);
            char y = fgetc(pPgmFile);

            if (x != 'P' || y != '5') {
                    fprintf(stderr, "Invalid PGM file '%s'.\n", pFileName);
                    return false;
            };

            uint32_t maxvalue;
            fscanf(pPgmFile, "%d", &width);
            fscanf(pPgmFile, "%d", &height);
            fscanf(pPgmFile, "%d", &maxvalue);

            if (maxvalue > 255) {
                    fprintf(stderr, "File '%s' has incorrect format.\nOnly 8-bit PGMs are supported by this reader.\n", pFileName);
                    return false;
            };

            ImgData = new uint8_t[width*height];
            memset(ImgData, 0, width*height);
            fgetc(pPgmFile);                // skip new line character
            uint32_t nPixelsRead = fread(ImgData, 1, width * height, pPgmFile);
            fclose(pPgmFile);

            if (nPixelsRead != width * height) {
                    fprintf(stderr, "PGM file '%s' does not contain all pixels.\n", pFileName);
                    return false;
            };

            return true;
    }

    return false;
};

Solution

  • The method declaration hides the static height and width variables.

    bool ReadImageFromPgmFile(const char* pFileName, 
        uint32_t &height, 
        uint32_t &width, 
        uint8_t*& ImgData) {
    

    Use of height and width in this method will refer to the local parameters and not the static variables. I cannot see any reference to imageData, though there is an ImgData parameter that is used.

    The static keyword in this context means the variables are only visible to the compilation unit it is declared in. Removing the static keyword makes it a global variable; accessible by the whole program. The compiler is unable (or unwilling) to reason about the usage of globals so you do not get the warnings.