My compiler is optimising something out that it shouldn't

My compiler, MPLAB C30 (GCC v3.23) is not compiling this code:

 if(font_info.flags & FONT_LOWERCASE_ONLY)
  ch = tolower(ch);
 if(font_info.flags & FONT_UPPERCASE_ONLY)
  ch = toupper(ch);

It produces no assembly output (somehow optimising it out) and I can't figure out why.

I have defined everything correctly as far as I can see:

#define FONT_LOWERCASE_ONLY  1
#define FONT_UPPERCASE_ONLY  2

struct FontEntry
{
 int id;
 unsigned char width, height;
 const char *name;
 const char *lookup;
 const char *data;
 int flags;
};

struct FontEntry fonts[NUM_FONTS + 1] = {
 { 0, 8, 14, "Outlined8x14", &font_lookup_outlined8x14, &font_data_outlined8x14, 0 },
 { 1, 8, 8, "Outlined8x8", &font_lookup_outlined8x8, &font_data_outlined8x8, FONT_UPPERCASE_ONLY }, 
 { 2, 8, 8, "Tiny5x5", 0, 0, 0 }, // not yet implemented
 { -1 } // ends font table
};

The function I am using is:

void write_char(char ch, unsigned int x, unsigned int y, int flags, int font)
{
 int i, yy, addr_temp, row, row_temp, xshift;
 uint16_t and_mask, or_mask, level_bits;
 struct FontEntry font_info;
 char lookup;
 fetch_font_info(ch, font, &font_info, &lookup);
    // ...
}

The definition of fetch_font_info:

int fetch_font_info(char ch, int font, struct FontEntry *font_info, char *lookup)
{
 // First locate the font struct.
 if(font > SIZEOF_ARRAY(fonts))
  return 0; // font does not exist, exit.
 // Load the font info; IDs are always sequential.
 *font_info = fonts[font];
 // Locate character in font lookup table. (If required.)
 if(lookup != NULL)
 {
  *lookup = font_info->lookup[ch];
  if(lookup == 0xff)
   return 0; // character doesn't exist, don't bother writing it.
 }
 return 1;
}

What am I doing wrong?

Answers


Is it possible you're acting on the return code from fetch_font_info() in write_char() (it's hard to know since the write_char() you've posted isn't what you're really compiling; some editing has happened)?

If you're acting on the return from fetch_font_info() then the problem might be cuased by the bug in testing the character pointed to by lookup:

if(lookup == 0xff) 

should be

if(*lookup == 0xff)

with the bugged test, fetch_font_info() will always return 0 if lookup is non-null.


Since FONT_LOWERCASE_ONLY and FONT_UPPERCASE_ONLY are non 0 then font_info.flags must always be 0 (or not have any 1s in the lower two bits). Compilers can be clever about how they evaluate "constants" even if you don't define them as such.

I see that your fonts array has a few 0s in the flag section so I am betting you have a hard coded reference to one of those entries at compile time.


Need Your Help

PHP GD Image Countdown No Longer Working

php image gd

This countdown script worked for the last couple of years. Nothing has changed with the script, but time, so I assume the code simply deprecated.

Amazon AWS For Whois?

php python amazon-web-services whois

I was looking for a Whois Api, but most of them charge heavy price and not reliable enough. We can code in Python or Php.