Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: c++ static member initialization (warning, hardcore :) )

  1. #1
    Senior Member Projectitis's Avatar
    Join Date
    Feb 2018
    Location
    New Zealand
    Posts
    183

    c++ static member initialization (warning, hardcore :) )

    Hi all,

    I have these defs:

    Code:
    enum class GUIIconType {
    	none = 0,
    	check,
    	checkCircle,
    	close,
    	closeCircle
    };
    
    typedef struct {
    	uint32_t index;
    	int8_t ox;
    	int8_t oy;
    	BitmapRotation r;
    } GUIIconPart;
    
    typedef struct {
    	uint8_t len;
    	GUIIconPart parts[];
    } GUIIconParts;
    
    typedef std::map<GUIIconType,GUIIconParts> GUIIconAllParts;
    And in the class I am trying to define a static member of type GUIIconAllParts like this:

    Code:
    static const GUIIconAllParts iconParts = {
    	{ GUIIconType::checkCircle, // GUIIconType
    		{ 2,	// GUIIconParts.len
    			{	// GUIIconParts.parts
    				{ 1, 0, 0, BitmapRotation::none },	// GUIIconPart
    				{ 30, 0, 0, BitmapRotation::none }	// GUIIconPart
    			}
    		}
    	}
    };
    The compile error I get is:

    Code:
    error: in-class initialization of static data member 'const GUIIconAllParts mac::GUIIcon::iconParts' of incomplete type
    
    error: could not convert '{{checkCircle, {2, {{1, 0, 0, none}, {30, 0, 0, none}}}}}' from '<brace-enclosed initializer list>' to 'const GUIIconAllParts {aka const std::map<mac::GUIIconType, mac::GUIIconParts>}'
    Where am I going wrong?

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,475
    There are two issues in your code.

    • You can not initialize non literal static types directly in the a class declaration. You need to do that in some cpp file
    • Your array GUIIconPart parts[] needs a defined length otherwise the compiler can't know how much space to allocate in your map


    Here something which compiles:

    test.h
    Code:
    #include "Arduino.h"
    #include <map>
    
    enum class GUIIconType {
    	none = 0,
    	check,
    	checkCircle,
    	close,
    	closeCircle
    };
    
    typedef struct {
    	uint32_t index;
    	int8_t ox;
    	int8_t oy;
    	//BitmapRotation r; // declaration missing but irrelevant for the example....
    } GUIIconPart;
    
    typedef struct {
    	uint8_t len;
    	GUIIconPart parts[4];  // need to define the length of the array
    } GUIIconParts;
    
    typedef std::map<GUIIconType,GUIIconParts> GUIIconAllParts;
    
    
    class Test
    {
        static const GUIIconAllParts iconParts;    
    };
    Here the corresponding definition of GUIIconAllParts:

    test.cpp
    Code:
    #include "test.h"
    
    const GUIIconAllParts Test::iconParts
    {
        {GUIIconType::checkCircle, 
          {2, 
            {
              {1, 0, 0},
              {30,0,0}
            }
          }
        },
        {GUIIconType::check, 
          {3, 
            {
              {4, 5, 6},
              {7, 8,12}
            }
           }
        }
    };
    Hope that helps
    Last edited by luni; 03-09-2021 at 11:00 AM.

  3. #3
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,475
    BTW: In case you don't know (or don't want to know) the size of your parts array beforehand you might consider changing it to vector<GUIIconPart>. If so, you probably don't need the uint8_t len anymore and you can make everything a bit simpler by directly using the vector of GUIIconParts in the map:

    test.h
    Code:
    #include "Arduino.h"
    #include <map>
    #include <vector>
    #pragma once
    
    enum class GUIIconType {
    	none = 0,
    	check,
    	checkCircle,
    	close,
    	closeCircle
    };
    
    struct GUIIconPart {           // typedef struct is somehow outdated. c++ can handle normal struct declarations
    	uint32_t index;
    	int8_t ox;
    	int8_t oy;
    	//BitmapRotation r;
    } ;
    
    using GUIIconAllParts = std::map<GUIIconType, std::vector<GUIIconPart>>;  // directly add the vector to the map...
    
    class Test
    {
        static const GUIIconAllParts iconParts;
    };
    test.cpp
    Code:
    #include "test.h"
    
    const GUIIconAllParts Test::iconParts
    {
      {
        GUIIconType::checkCircle, 
        {
          {1, 0, 0},
          {30,0,0}       
        }
      },
      {
        GUIIconType::closeCircle, 
        {
          {4, 5, 6},
          {7, 8,12},
          {4, 5, 6},
          {7, 8,12},
          {4, 5, 6},
          {7, 8,12}
        }
      }   
    };

  4. #4
    Senior Member Projectitis's Avatar
    Join Date
    Feb 2018
    Location
    New Zealand
    Posts
    183
    Awesome! On both counts. Vector solves my problem here, as long as the overhead of adding the vector library isnít bigger than assigning fixed length arrays Will check tonight. There will be something like 200 icons in the list, each made up of between 1 and 3 parts.

  5. #5
    Senior Member Projectitis's Avatar
    Join Date
    Feb 2018
    Location
    New Zealand
    Posts
    183
    Quote Originally Posted by Projectitis View Post
    Awesome! On both counts. Vector solves my problem here, as long as the overhead of adding the vector library isnít bigger than assigning fixed length arrays Will check tonight. There will be something like 200 icons in the list, each made up of between 1 and 3 parts.
    So if I pack my data:
    • 200 icons with 2 parts on average each
    • 1 byte overhead for each icon (len)
    • Each part 4 bytes long

    I'll end up with around 1.8k of data. this is the minimum I can hope for.
    Just adding map and vector to the project add 49k of flash!!
    So I'll pack my data and iterate instead of using a map

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    1,475
    He, he, there is no such thing as a free lunch On the other hand, NXP won't refund any money for unused flash bytes... :-))

  7. #7
    Senior Member Projectitis's Avatar
    Join Date
    Feb 2018
    Location
    New Zealand
    Posts
    183
    Haha! That is true. But I hate seeing that counter increase it's over 10% now - arrrgh
    I enjoy a challenge anyway.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •