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

App Rejected for failing to launch? …and others

iphone objective-c ios

My game was just rejected from the AppStore for the following two reasons...

Linux user space: how to put 16550-compatible UART in loopback mode persistently

linux loopback uart

There is an 16550-compatible UART on the market that I would like to configure. The Linux driver is provided by the manufacturer, and I have to configure the (multiple-)UART through an user-space

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.