question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Backwards compatibility issue with C++ compilation

See original GitHub issue

Issue Description

Some older versions of C++ compilers require that structs be initialized in the same order that they are declared. The current version of lv_font_conv generates .c font files that have some structs that do not meet his criteria.

Indicative Error

Compilation crashes with this error message: sorry, unimplemented: non-trivial designated initializers not supported

Issue example

Struct declaration from lv_font.h in the LittlevGL library:

{
    uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width. 8 bit integer, 4 bit fractional */
    uint8_t box_w;  /**< Width of the glyph's bounding box*/
    uint8_t box_h;  /**< Height of the glyph's bounding box*/
    int8_t ofs_x;   /**< x offset of the bounding box*/
    int8_t ofs_y;  /**< y offset of the bounding box*/
    uint8_t bpp;   /**< Bit-per-pixel: 1, 2, 4, 8*/
}lv_font_glyph_dsc_t;

An example of the same struct that is generated in a font file by the current version of lv_font_conv:

static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
    {.bitmap_index = 0, .adv_w = 99, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},
    {.bitmap_index = 0, .adv_w = 70, .box_h = 15, .box_w = 3, .ofs_x = 1, .ofs_y = 0},
    {.bitmap_index = 6, .adv_w = 119, .box_h = 5, .box_w = 6, .ofs_x = 1, .ofs_y = 10},
    {.bitmap_index = 10, .adv_w = 255, .box_h = 15, .box_w = 16, .ofs_x = 0, .ofs_y = 0},
    {.bitmap_index = 40, .adv_w = 252, .box_h = 18, .box_w = 15, .ofs_x = 1, .ofs_y = -2},
    {.bitmap_index = 74, .adv_w = 309, .box_h = 15, .box_w = 17, .ofs_x = 1, .ofs_y = 0},
    {.bitmap_index = 106, .adv_w = 300, .box_h = 15, .box_w = 18, .ofs_x = 1, .ofs_y = 0},
   ..................
   ..................
}

Notice that: The .box_h and .box_w parameters in the generated struct are out of order with the struct declaration in lv_font.h

Suggested fix

There are 3 files in the lv_font_conv project that are responsible for generating the affected structs found in the font file:

  1. lv_table_cmap.js
  2. lv_table_glyf.js
  3. lv_table_head.js

The affected structs are:

  1. lv_font_fmt_txt_glyph_dsc_t
  2. lv_font_fmt_txt_cmap_t
  3. lv_font_fmt_txt_kern_pair_t
  4. lv_font_fmt_txt_dsc_t
  5. lv_font_t example_font

Fix example

From lv_table.glyf.js

  to_lv_glyph_dsc() {
    this.lv_compile();

    /* eslint-disable max-len */

    let result = [ '    {.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */' ];

    this.lv_data.forEach(d => {
      const idx = d.offset,
            adv_w = Math.round(d.glyph.advanceWidth * 16),
            h = d.glyph.bbox.height,
            w = d.glyph.bbox.width,
            x = d.glyph.bbox.x,
            y = d.glyph.bbox.y;
      result.push(`    {.bitmap_index = ${idx}, .adv_w = ${adv_w}, .box_h = ${h}, .box_w = ${w}, .ofs_x = ${x}, .ofs_y = ${y}}`);
    });

    return result.join(',\n');
  }

should become:

  to_lv_glyph_dsc() {
    this.lv_compile();

    /* eslint-disable max-len */

    let result = [ '    {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */' ];

    this.lv_data.forEach(d => {
      const idx = d.offset,
            adv_w = Math.round(d.glyph.advanceWidth * 16),
            h = d.glyph.bbox.height,
            w = d.glyph.bbox.width,
            x = d.glyph.bbox.x,
            y = d.glyph.bbox.y;
      result.push(`    {.bitmap_index = ${idx}, .adv_w = ${adv_w}, .box_w = ${h}, .box_h = ${w}, .ofs_x = ${x}, .ofs_y = ${y}}`);
    });

    return result.join(',\n');
  }

Reproduction and conclusion

I am using g++ as a C++ compiler: Target: x86_64-linux-gnu gcc version: 7.4.0

Apparently newer versions of the g++ compiler allow out-of-order struct initialization. I seem to remember seeing version 8.0.0 and newer supports that. However, many hardware projects have version constraints: for example I can only use 7.4.0. It would be a good idea to make this fix for backwards-compatibility’s sake. I would do it myself but there are legal issues that prevent me from doing so. Hopefully I have given enough information for it to be an easy fix for whoever picks it up.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
puzrincommented, Sep 26, 2019

done

1reaction
jared-nelsencommented, Sep 26, 2019

I’ve built and used the changes you made on the dev branch. It works great! The changes you made are exactly the ones we needed. Thanks @puzrin !

I am on board for merging these changes to master.

Thanks for all the help! My team is really loving lvgl @kisvegabor !

Read more comments on GitHub >

github_iconTop Results From Across the Web

Are C versions backwards compatible? - Stack Overflow
C standards are not backward compatible - code written under the latest standard is not guaranteed to build with compilers that only support ......
Read more >
What If C++ Abandoned Backward Compatibility? | Hacker News
So much of C++'s success is due to backward compatibility. ... It's a compiler issue, thus if anything that code needs to be...
Read more >
Backward Compatibility - Microsoft Learn
For compatibility between product versions, the library OLDNAMES.LIB maps old names to new names. For instance, open maps to _open .
Read more >
Backwards Compatibility (Using the GNU Compiler Collection ...
In order to allow compilation of C++ written to such drafts, G++ contains some backwards compatibilities. All such backwards compatibility features are liable ......
Read more >
Backward compatibility issues - IBM
This section describes backward compatibility issues and their workarounds. Compiler option compatibility issues. In IBM XL C/C++ for Linux, V11.1, the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found