How to create a “spacer” in the C++ class memory structure?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite
1












The issue



In a low level bare-metal embedded context, I would like to create a blank space in the memory, within a C++ structure and without any name, to forbid the user to access such memory location.



Right now, I have achieved to do so by putting an ugly uint32_t :96; bitfield which will conveniently take place of 3 words but will raise a warning from GCC (Bitfield too large to fit in uint32_t, which is pretty legit).



While it works fine, it is not very clean when you want to distribute a library with several hundreds of those warnings...



Do someone know how to do that properly ?



Why is there an issue in the first place ?



The project I'm working on consist in defining the memory structure of different peripherals of a whole MCU line (STMicroelectronics STM32). To do so, the result is a class which contains an union of several structures which defines all registers, depending on the targeted MCU.



One simple example is the following, for a pretty simple peripheral : a General Purpose Input/Output (GPIO)



union


struct

GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
;
struct

GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
;
struct

uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
;
;


Where all GPIO_MAPx_YYY is a macro, defined either as uint32_t :32 or the register type. (A dedicated structure)



Here you see the uint32_t :192; which works well but trigger a warning.



I might have replaced it by several uint32_t :32; (here 6) but I have some extreme cases where I have uint32_t :1344; (42) (among others). So I would rather not add about one hundred lines on top of 8k others, even though the structure generation is scripted.



By the way, all posted code is working absolutely (and surprisingly) fine.



Best regards,
Julien



Edits...



Edit 1



The exact warning message is something like this :
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type. (I just love how shady it is)



I would rather not solve this by simply removing the warning, but the use of



#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop


May be a solution... If I find TheRightFlag



Edit 2



In the same way as pointed out in this thread, gcc/cp/class.c hold this sad code part :



warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);


Which tells us that there is no -Wxxx flag to remove this warning...










share|improve this question









New contributor




J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 7




    have you consided char unused[12]; and so on?
    – M.M
    3 hours ago






  • 1




    This is a well done question. Good job! I'd like to know the answer myself.
    – Christopher Pisz
    3 hours ago






  • 1




    I would just suppress the warning. [class.bit]/1 guarantees the behavior of uint32_t :192;.
    – NathanOliver
    3 hours ago






  • 1




    @NathanOliver I would gladly too, but it seems that this warning is not suppressible (Using GCC) or I didn't find how to do so. Moreover, it still is not a clean way to do (but it would be pretty satisfying) . I managed to find the correct "-W" flag but didn't manage to apply it only on my own files (I don't want the user to remove this kind of warnings for his work)
    – J Faucher
    2 hours ago







  • 1




    BTW you can write :42*32 instead of :1344
    – M.M
    2 hours ago














up vote
8
down vote

favorite
1












The issue



In a low level bare-metal embedded context, I would like to create a blank space in the memory, within a C++ structure and without any name, to forbid the user to access such memory location.



Right now, I have achieved to do so by putting an ugly uint32_t :96; bitfield which will conveniently take place of 3 words but will raise a warning from GCC (Bitfield too large to fit in uint32_t, which is pretty legit).



While it works fine, it is not very clean when you want to distribute a library with several hundreds of those warnings...



Do someone know how to do that properly ?



Why is there an issue in the first place ?



The project I'm working on consist in defining the memory structure of different peripherals of a whole MCU line (STMicroelectronics STM32). To do so, the result is a class which contains an union of several structures which defines all registers, depending on the targeted MCU.



One simple example is the following, for a pretty simple peripheral : a General Purpose Input/Output (GPIO)



union


struct

GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
;
struct

GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
;
struct

uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
;
;


Where all GPIO_MAPx_YYY is a macro, defined either as uint32_t :32 or the register type. (A dedicated structure)



Here you see the uint32_t :192; which works well but trigger a warning.



I might have replaced it by several uint32_t :32; (here 6) but I have some extreme cases where I have uint32_t :1344; (42) (among others). So I would rather not add about one hundred lines on top of 8k others, even though the structure generation is scripted.



By the way, all posted code is working absolutely (and surprisingly) fine.



Best regards,
Julien



Edits...



Edit 1



The exact warning message is something like this :
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type. (I just love how shady it is)



I would rather not solve this by simply removing the warning, but the use of



#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop


May be a solution... If I find TheRightFlag



Edit 2



In the same way as pointed out in this thread, gcc/cp/class.c hold this sad code part :



warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);


Which tells us that there is no -Wxxx flag to remove this warning...










share|improve this question









New contributor




J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 7




    have you consided char unused[12]; and so on?
    – M.M
    3 hours ago






  • 1




    This is a well done question. Good job! I'd like to know the answer myself.
    – Christopher Pisz
    3 hours ago






  • 1




    I would just suppress the warning. [class.bit]/1 guarantees the behavior of uint32_t :192;.
    – NathanOliver
    3 hours ago






  • 1




    @NathanOliver I would gladly too, but it seems that this warning is not suppressible (Using GCC) or I didn't find how to do so. Moreover, it still is not a clean way to do (but it would be pretty satisfying) . I managed to find the correct "-W" flag but didn't manage to apply it only on my own files (I don't want the user to remove this kind of warnings for his work)
    – J Faucher
    2 hours ago







  • 1




    BTW you can write :42*32 instead of :1344
    – M.M
    2 hours ago












up vote
8
down vote

favorite
1









up vote
8
down vote

favorite
1






1





The issue



In a low level bare-metal embedded context, I would like to create a blank space in the memory, within a C++ structure and without any name, to forbid the user to access such memory location.



Right now, I have achieved to do so by putting an ugly uint32_t :96; bitfield which will conveniently take place of 3 words but will raise a warning from GCC (Bitfield too large to fit in uint32_t, which is pretty legit).



While it works fine, it is not very clean when you want to distribute a library with several hundreds of those warnings...



Do someone know how to do that properly ?



Why is there an issue in the first place ?



The project I'm working on consist in defining the memory structure of different peripherals of a whole MCU line (STMicroelectronics STM32). To do so, the result is a class which contains an union of several structures which defines all registers, depending on the targeted MCU.



One simple example is the following, for a pretty simple peripheral : a General Purpose Input/Output (GPIO)



union


struct

GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
;
struct

GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
;
struct

uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
;
;


Where all GPIO_MAPx_YYY is a macro, defined either as uint32_t :32 or the register type. (A dedicated structure)



Here you see the uint32_t :192; which works well but trigger a warning.



I might have replaced it by several uint32_t :32; (here 6) but I have some extreme cases where I have uint32_t :1344; (42) (among others). So I would rather not add about one hundred lines on top of 8k others, even though the structure generation is scripted.



By the way, all posted code is working absolutely (and surprisingly) fine.



Best regards,
Julien



Edits...



Edit 1



The exact warning message is something like this :
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type. (I just love how shady it is)



I would rather not solve this by simply removing the warning, but the use of



#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop


May be a solution... If I find TheRightFlag



Edit 2



In the same way as pointed out in this thread, gcc/cp/class.c hold this sad code part :



warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);


Which tells us that there is no -Wxxx flag to remove this warning...










share|improve this question









New contributor




J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











The issue



In a low level bare-metal embedded context, I would like to create a blank space in the memory, within a C++ structure and without any name, to forbid the user to access such memory location.



Right now, I have achieved to do so by putting an ugly uint32_t :96; bitfield which will conveniently take place of 3 words but will raise a warning from GCC (Bitfield too large to fit in uint32_t, which is pretty legit).



While it works fine, it is not very clean when you want to distribute a library with several hundreds of those warnings...



Do someone know how to do that properly ?



Why is there an issue in the first place ?



The project I'm working on consist in defining the memory structure of different peripherals of a whole MCU line (STMicroelectronics STM32). To do so, the result is a class which contains an union of several structures which defines all registers, depending on the targeted MCU.



One simple example is the following, for a pretty simple peripheral : a General Purpose Input/Output (GPIO)



union


struct

GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
;
struct

GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
;
struct

uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
;
;


Where all GPIO_MAPx_YYY is a macro, defined either as uint32_t :32 or the register type. (A dedicated structure)



Here you see the uint32_t :192; which works well but trigger a warning.



I might have replaced it by several uint32_t :32; (here 6) but I have some extreme cases where I have uint32_t :1344; (42) (among others). So I would rather not add about one hundred lines on top of 8k others, even though the structure generation is scripted.



By the way, all posted code is working absolutely (and surprisingly) fine.



Best regards,
Julien



Edits...



Edit 1



The exact warning message is something like this :
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type. (I just love how shady it is)



I would rather not solve this by simply removing the warning, but the use of



#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop


May be a solution... If I find TheRightFlag



Edit 2



In the same way as pointed out in this thread, gcc/cp/class.c hold this sad code part :



warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);


Which tells us that there is no -Wxxx flag to remove this warning...







c++ c memory-management low-level bare-metal






share|improve this question









New contributor




J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 1 hour ago





















New contributor




J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 3 hours ago









J Faucher

412




412




New contributor




J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






J Faucher is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 7




    have you consided char unused[12]; and so on?
    – M.M
    3 hours ago






  • 1




    This is a well done question. Good job! I'd like to know the answer myself.
    – Christopher Pisz
    3 hours ago






  • 1




    I would just suppress the warning. [class.bit]/1 guarantees the behavior of uint32_t :192;.
    – NathanOliver
    3 hours ago






  • 1




    @NathanOliver I would gladly too, but it seems that this warning is not suppressible (Using GCC) or I didn't find how to do so. Moreover, it still is not a clean way to do (but it would be pretty satisfying) . I managed to find the correct "-W" flag but didn't manage to apply it only on my own files (I don't want the user to remove this kind of warnings for his work)
    – J Faucher
    2 hours ago







  • 1




    BTW you can write :42*32 instead of :1344
    – M.M
    2 hours ago












  • 7




    have you consided char unused[12]; and so on?
    – M.M
    3 hours ago






  • 1




    This is a well done question. Good job! I'd like to know the answer myself.
    – Christopher Pisz
    3 hours ago






  • 1




    I would just suppress the warning. [class.bit]/1 guarantees the behavior of uint32_t :192;.
    – NathanOliver
    3 hours ago






  • 1




    @NathanOliver I would gladly too, but it seems that this warning is not suppressible (Using GCC) or I didn't find how to do so. Moreover, it still is not a clean way to do (but it would be pretty satisfying) . I managed to find the correct "-W" flag but didn't manage to apply it only on my own files (I don't want the user to remove this kind of warnings for his work)
    – J Faucher
    2 hours ago







  • 1




    BTW you can write :42*32 instead of :1344
    – M.M
    2 hours ago







7




7




have you consided char unused[12]; and so on?
– M.M
3 hours ago




have you consided char unused[12]; and so on?
– M.M
3 hours ago




1




1




This is a well done question. Good job! I'd like to know the answer myself.
– Christopher Pisz
3 hours ago




This is a well done question. Good job! I'd like to know the answer myself.
– Christopher Pisz
3 hours ago




1




1




I would just suppress the warning. [class.bit]/1 guarantees the behavior of uint32_t :192;.
– NathanOliver
3 hours ago




I would just suppress the warning. [class.bit]/1 guarantees the behavior of uint32_t :192;.
– NathanOliver
3 hours ago




1




1




@NathanOliver I would gladly too, but it seems that this warning is not suppressible (Using GCC) or I didn't find how to do so. Moreover, it still is not a clean way to do (but it would be pretty satisfying) . I managed to find the correct "-W" flag but didn't manage to apply it only on my own files (I don't want the user to remove this kind of warnings for his work)
– J Faucher
2 hours ago





@NathanOliver I would gladly too, but it seems that this warning is not suppressible (Using GCC) or I didn't find how to do so. Moreover, it still is not a clean way to do (but it would be pretty satisfying) . I managed to find the correct "-W" flag but didn't manage to apply it only on my own files (I don't want the user to remove this kind of warnings for his work)
– J Faucher
2 hours ago





1




1




BTW you can write :42*32 instead of :1344
– M.M
2 hours ago




BTW you can write :42*32 instead of :1344
– M.M
2 hours ago












4 Answers
4






active

oldest

votes

















up vote
2
down vote













In the embedded systems arena, you can model hardware either by using a structure or by defining pointers to the register addresses.



Modeling by structure is not recommended because the compiler is allowed to add padding between members for alignment purposes (although many compilers for embedded systems have a pragma for packing the structure).



Example:



uint16_t * const UART1 = (uint16_t *)(0x40000);
const unsigned int UART_STATUS_OFFSET = 1U;
const unsigned int UART_TRANSMIT_REGISTER = 2U;
uint16_t * const UART1_STATUS_REGISTER = (UART1 + UART_STATUS_OFFSET);
uint16_t * const UART1_TRANSMIT_REGISTER = (UART1 + UART_TRANSMIT_REGISTER);


You could also use the array notation:



uint16_t status = UART1[UART_STATUS_OFFSET]; 


If you must use the structure, IMHO, the best method to skip addresses would be to define a member and not access it:



struct UART1

uint16_t status;
uint16_t reserved1; // Transmit register
uint16_t receive_register;
;


In one of our projects we have both constants and structs from different vendors (vendor 1 uses constants while vendor 2 uses structures).






share|improve this answer




















  • Thanks for your answer. However, I choose to use a structure approach to ease the work of the user when he got an auto-complete feature (You only will have the right attributes displayed) and I don't want to "show" the user the reserved slots as pointed out in a comment of my first post.
    – J Faucher
    2 hours ago










  • You can still have that by making the above address static members of a structure assuming that autocomplete is able to show static members. If not, it can be inline member functions too.
    – Phil1970
    just now

















up vote
2
down vote













Use multiple adjacent anonymous bitfields. So instead of:



 uint32_t :160;


for example, you'd have:



 uint32_t :32;
uint32_t :32;
uint32_t :32;
uint32_t :32;
uint32_t :32;


One for each register you want to be anonymous.






share|improve this answer




















  • Thanks for the answer. I already considered that, however it would add over 200 lines on some of my files (uint32_t :1344; is in the place) so I would rather not have to go this way...
    – J Faucher
    1 hour ago

















up vote
1
down vote













To expand on Clifford's answer, you can always macro out the anonymous bitfields.



So instead of



uint32_t :160;


use



#define EMPTY_32_1 
uint32_t :32
#define EMPTY_32_2
uint32_t :32;
uint32_t :32
#define EMPTY_32_3
uint32_t :32;
uint32_t :32;
uint32_t :32
#define EMPTY_UINT32(N) EMPTY_32_ ## N


And then use it like



struct A 
EMPTY_UINT32(3);
/* which resolves to EMPTY_32_3, which then resolves to real declarations */



Unfortunately, you'll need as many EMPTY_32_X variants as many bytes you have :(
Still, it allows you to have single declarations in your struct.





share



























    up vote
    0
    down vote













    How about a C++-ish way?



    namespace GPIO 

    inline uint32_t &MAP0_MODER = *reinterpret_cast<uint32_t*>(0x4000);
    inline uint32_t &MAP0_OTYPER = *reinterpret_cast<uint32_t*>(0x4004);



    int main()
    GPIO::MAP0_MODER = 42;



    You get autocompletion because of the GPIO namespace, and there is no need for dummy padding. Even, it is more clear what's going on, as you can see the address of each register, you don't have to rely on the compiler's padding behavior at all.






    share|improve this answer




















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );






      J Faucher is a new contributor. Be nice, and check out our Code of Conduct.









       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53109888%2fhow-to-create-a-spacer-in-the-c-class-memory-structure%23new-answer', 'question_page');

      );

      Post as a guest






























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote













      In the embedded systems arena, you can model hardware either by using a structure or by defining pointers to the register addresses.



      Modeling by structure is not recommended because the compiler is allowed to add padding between members for alignment purposes (although many compilers for embedded systems have a pragma for packing the structure).



      Example:



      uint16_t * const UART1 = (uint16_t *)(0x40000);
      const unsigned int UART_STATUS_OFFSET = 1U;
      const unsigned int UART_TRANSMIT_REGISTER = 2U;
      uint16_t * const UART1_STATUS_REGISTER = (UART1 + UART_STATUS_OFFSET);
      uint16_t * const UART1_TRANSMIT_REGISTER = (UART1 + UART_TRANSMIT_REGISTER);


      You could also use the array notation:



      uint16_t status = UART1[UART_STATUS_OFFSET]; 


      If you must use the structure, IMHO, the best method to skip addresses would be to define a member and not access it:



      struct UART1

      uint16_t status;
      uint16_t reserved1; // Transmit register
      uint16_t receive_register;
      ;


      In one of our projects we have both constants and structs from different vendors (vendor 1 uses constants while vendor 2 uses structures).






      share|improve this answer




















      • Thanks for your answer. However, I choose to use a structure approach to ease the work of the user when he got an auto-complete feature (You only will have the right attributes displayed) and I don't want to "show" the user the reserved slots as pointed out in a comment of my first post.
        – J Faucher
        2 hours ago










      • You can still have that by making the above address static members of a structure assuming that autocomplete is able to show static members. If not, it can be inline member functions too.
        – Phil1970
        just now














      up vote
      2
      down vote













      In the embedded systems arena, you can model hardware either by using a structure or by defining pointers to the register addresses.



      Modeling by structure is not recommended because the compiler is allowed to add padding between members for alignment purposes (although many compilers for embedded systems have a pragma for packing the structure).



      Example:



      uint16_t * const UART1 = (uint16_t *)(0x40000);
      const unsigned int UART_STATUS_OFFSET = 1U;
      const unsigned int UART_TRANSMIT_REGISTER = 2U;
      uint16_t * const UART1_STATUS_REGISTER = (UART1 + UART_STATUS_OFFSET);
      uint16_t * const UART1_TRANSMIT_REGISTER = (UART1 + UART_TRANSMIT_REGISTER);


      You could also use the array notation:



      uint16_t status = UART1[UART_STATUS_OFFSET]; 


      If you must use the structure, IMHO, the best method to skip addresses would be to define a member and not access it:



      struct UART1

      uint16_t status;
      uint16_t reserved1; // Transmit register
      uint16_t receive_register;
      ;


      In one of our projects we have both constants and structs from different vendors (vendor 1 uses constants while vendor 2 uses structures).






      share|improve this answer




















      • Thanks for your answer. However, I choose to use a structure approach to ease the work of the user when he got an auto-complete feature (You only will have the right attributes displayed) and I don't want to "show" the user the reserved slots as pointed out in a comment of my first post.
        – J Faucher
        2 hours ago










      • You can still have that by making the above address static members of a structure assuming that autocomplete is able to show static members. If not, it can be inline member functions too.
        – Phil1970
        just now












      up vote
      2
      down vote










      up vote
      2
      down vote









      In the embedded systems arena, you can model hardware either by using a structure or by defining pointers to the register addresses.



      Modeling by structure is not recommended because the compiler is allowed to add padding between members for alignment purposes (although many compilers for embedded systems have a pragma for packing the structure).



      Example:



      uint16_t * const UART1 = (uint16_t *)(0x40000);
      const unsigned int UART_STATUS_OFFSET = 1U;
      const unsigned int UART_TRANSMIT_REGISTER = 2U;
      uint16_t * const UART1_STATUS_REGISTER = (UART1 + UART_STATUS_OFFSET);
      uint16_t * const UART1_TRANSMIT_REGISTER = (UART1 + UART_TRANSMIT_REGISTER);


      You could also use the array notation:



      uint16_t status = UART1[UART_STATUS_OFFSET]; 


      If you must use the structure, IMHO, the best method to skip addresses would be to define a member and not access it:



      struct UART1

      uint16_t status;
      uint16_t reserved1; // Transmit register
      uint16_t receive_register;
      ;


      In one of our projects we have both constants and structs from different vendors (vendor 1 uses constants while vendor 2 uses structures).






      share|improve this answer












      In the embedded systems arena, you can model hardware either by using a structure or by defining pointers to the register addresses.



      Modeling by structure is not recommended because the compiler is allowed to add padding between members for alignment purposes (although many compilers for embedded systems have a pragma for packing the structure).



      Example:



      uint16_t * const UART1 = (uint16_t *)(0x40000);
      const unsigned int UART_STATUS_OFFSET = 1U;
      const unsigned int UART_TRANSMIT_REGISTER = 2U;
      uint16_t * const UART1_STATUS_REGISTER = (UART1 + UART_STATUS_OFFSET);
      uint16_t * const UART1_TRANSMIT_REGISTER = (UART1 + UART_TRANSMIT_REGISTER);


      You could also use the array notation:



      uint16_t status = UART1[UART_STATUS_OFFSET]; 


      If you must use the structure, IMHO, the best method to skip addresses would be to define a member and not access it:



      struct UART1

      uint16_t status;
      uint16_t reserved1; // Transmit register
      uint16_t receive_register;
      ;


      In one of our projects we have both constants and structs from different vendors (vendor 1 uses constants while vendor 2 uses structures).







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 2 hours ago









      Thomas Matthews

      43.5k1168119




      43.5k1168119











      • Thanks for your answer. However, I choose to use a structure approach to ease the work of the user when he got an auto-complete feature (You only will have the right attributes displayed) and I don't want to "show" the user the reserved slots as pointed out in a comment of my first post.
        – J Faucher
        2 hours ago










      • You can still have that by making the above address static members of a structure assuming that autocomplete is able to show static members. If not, it can be inline member functions too.
        – Phil1970
        just now
















      • Thanks for your answer. However, I choose to use a structure approach to ease the work of the user when he got an auto-complete feature (You only will have the right attributes displayed) and I don't want to "show" the user the reserved slots as pointed out in a comment of my first post.
        – J Faucher
        2 hours ago










      • You can still have that by making the above address static members of a structure assuming that autocomplete is able to show static members. If not, it can be inline member functions too.
        – Phil1970
        just now















      Thanks for your answer. However, I choose to use a structure approach to ease the work of the user when he got an auto-complete feature (You only will have the right attributes displayed) and I don't want to "show" the user the reserved slots as pointed out in a comment of my first post.
      – J Faucher
      2 hours ago




      Thanks for your answer. However, I choose to use a structure approach to ease the work of the user when he got an auto-complete feature (You only will have the right attributes displayed) and I don't want to "show" the user the reserved slots as pointed out in a comment of my first post.
      – J Faucher
      2 hours ago












      You can still have that by making the above address static members of a structure assuming that autocomplete is able to show static members. If not, it can be inline member functions too.
      – Phil1970
      just now




      You can still have that by making the above address static members of a structure assuming that autocomplete is able to show static members. If not, it can be inline member functions too.
      – Phil1970
      just now












      up vote
      2
      down vote













      Use multiple adjacent anonymous bitfields. So instead of:



       uint32_t :160;


      for example, you'd have:



       uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;


      One for each register you want to be anonymous.






      share|improve this answer




















      • Thanks for the answer. I already considered that, however it would add over 200 lines on some of my files (uint32_t :1344; is in the place) so I would rather not have to go this way...
        – J Faucher
        1 hour ago














      up vote
      2
      down vote













      Use multiple adjacent anonymous bitfields. So instead of:



       uint32_t :160;


      for example, you'd have:



       uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;


      One for each register you want to be anonymous.






      share|improve this answer




















      • Thanks for the answer. I already considered that, however it would add over 200 lines on some of my files (uint32_t :1344; is in the place) so I would rather not have to go this way...
        – J Faucher
        1 hour ago












      up vote
      2
      down vote










      up vote
      2
      down vote









      Use multiple adjacent anonymous bitfields. So instead of:



       uint32_t :160;


      for example, you'd have:



       uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;


      One for each register you want to be anonymous.






      share|improve this answer












      Use multiple adjacent anonymous bitfields. So instead of:



       uint32_t :160;


      for example, you'd have:



       uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;
      uint32_t :32;


      One for each register you want to be anonymous.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 2 hours ago









      Clifford

      57k857121




      57k857121











      • Thanks for the answer. I already considered that, however it would add over 200 lines on some of my files (uint32_t :1344; is in the place) so I would rather not have to go this way...
        – J Faucher
        1 hour ago
















      • Thanks for the answer. I already considered that, however it would add over 200 lines on some of my files (uint32_t :1344; is in the place) so I would rather not have to go this way...
        – J Faucher
        1 hour ago















      Thanks for the answer. I already considered that, however it would add over 200 lines on some of my files (uint32_t :1344; is in the place) so I would rather not have to go this way...
      – J Faucher
      1 hour ago




      Thanks for the answer. I already considered that, however it would add over 200 lines on some of my files (uint32_t :1344; is in the place) so I would rather not have to go this way...
      – J Faucher
      1 hour ago










      up vote
      1
      down vote













      To expand on Clifford's answer, you can always macro out the anonymous bitfields.



      So instead of



      uint32_t :160;


      use



      #define EMPTY_32_1 
      uint32_t :32
      #define EMPTY_32_2
      uint32_t :32;
      uint32_t :32
      #define EMPTY_32_3
      uint32_t :32;
      uint32_t :32;
      uint32_t :32
      #define EMPTY_UINT32(N) EMPTY_32_ ## N


      And then use it like



      struct A 
      EMPTY_UINT32(3);
      /* which resolves to EMPTY_32_3, which then resolves to real declarations */



      Unfortunately, you'll need as many EMPTY_32_X variants as many bytes you have :(
      Still, it allows you to have single declarations in your struct.





      share
























        up vote
        1
        down vote













        To expand on Clifford's answer, you can always macro out the anonymous bitfields.



        So instead of



        uint32_t :160;


        use



        #define EMPTY_32_1 
        uint32_t :32
        #define EMPTY_32_2
        uint32_t :32;
        uint32_t :32
        #define EMPTY_32_3
        uint32_t :32;
        uint32_t :32;
        uint32_t :32
        #define EMPTY_UINT32(N) EMPTY_32_ ## N


        And then use it like



        struct A 
        EMPTY_UINT32(3);
        /* which resolves to EMPTY_32_3, which then resolves to real declarations */



        Unfortunately, you'll need as many EMPTY_32_X variants as many bytes you have :(
        Still, it allows you to have single declarations in your struct.





        share






















          up vote
          1
          down vote










          up vote
          1
          down vote









          To expand on Clifford's answer, you can always macro out the anonymous bitfields.



          So instead of



          uint32_t :160;


          use



          #define EMPTY_32_1 
          uint32_t :32
          #define EMPTY_32_2
          uint32_t :32;
          uint32_t :32
          #define EMPTY_32_3
          uint32_t :32;
          uint32_t :32;
          uint32_t :32
          #define EMPTY_UINT32(N) EMPTY_32_ ## N


          And then use it like



          struct A 
          EMPTY_UINT32(3);
          /* which resolves to EMPTY_32_3, which then resolves to real declarations */



          Unfortunately, you'll need as many EMPTY_32_X variants as many bytes you have :(
          Still, it allows you to have single declarations in your struct.





          share












          To expand on Clifford's answer, you can always macro out the anonymous bitfields.



          So instead of



          uint32_t :160;


          use



          #define EMPTY_32_1 
          uint32_t :32
          #define EMPTY_32_2
          uint32_t :32;
          uint32_t :32
          #define EMPTY_32_3
          uint32_t :32;
          uint32_t :32;
          uint32_t :32
          #define EMPTY_UINT32(N) EMPTY_32_ ## N


          And then use it like



          struct A 
          EMPTY_UINT32(3);
          /* which resolves to EMPTY_32_3, which then resolves to real declarations */



          Unfortunately, you'll need as many EMPTY_32_X variants as many bytes you have :(
          Still, it allows you to have single declarations in your struct.






          share











          share


          share










          answered 6 mins ago









          Adam Kotwasinski

          1,629521




          1,629521




















              up vote
              0
              down vote













              How about a C++-ish way?



              namespace GPIO 

              inline uint32_t &MAP0_MODER = *reinterpret_cast<uint32_t*>(0x4000);
              inline uint32_t &MAP0_OTYPER = *reinterpret_cast<uint32_t*>(0x4004);



              int main()
              GPIO::MAP0_MODER = 42;



              You get autocompletion because of the GPIO namespace, and there is no need for dummy padding. Even, it is more clear what's going on, as you can see the address of each register, you don't have to rely on the compiler's padding behavior at all.






              share|improve this answer
























                up vote
                0
                down vote













                How about a C++-ish way?



                namespace GPIO 

                inline uint32_t &MAP0_MODER = *reinterpret_cast<uint32_t*>(0x4000);
                inline uint32_t &MAP0_OTYPER = *reinterpret_cast<uint32_t*>(0x4004);



                int main()
                GPIO::MAP0_MODER = 42;



                You get autocompletion because of the GPIO namespace, and there is no need for dummy padding. Even, it is more clear what's going on, as you can see the address of each register, you don't have to rely on the compiler's padding behavior at all.






                share|improve this answer






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  How about a C++-ish way?



                  namespace GPIO 

                  inline uint32_t &MAP0_MODER = *reinterpret_cast<uint32_t*>(0x4000);
                  inline uint32_t &MAP0_OTYPER = *reinterpret_cast<uint32_t*>(0x4004);



                  int main()
                  GPIO::MAP0_MODER = 42;



                  You get autocompletion because of the GPIO namespace, and there is no need for dummy padding. Even, it is more clear what's going on, as you can see the address of each register, you don't have to rely on the compiler's padding behavior at all.






                  share|improve this answer












                  How about a C++-ish way?



                  namespace GPIO 

                  inline uint32_t &MAP0_MODER = *reinterpret_cast<uint32_t*>(0x4000);
                  inline uint32_t &MAP0_OTYPER = *reinterpret_cast<uint32_t*>(0x4004);



                  int main()
                  GPIO::MAP0_MODER = 42;



                  You get autocompletion because of the GPIO namespace, and there is no need for dummy padding. Even, it is more clear what's going on, as you can see the address of each register, you don't have to rely on the compiler's padding behavior at all.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 22 mins ago









                  geza

                  10.6k22669




                  10.6k22669




















                      J Faucher is a new contributor. Be nice, and check out our Code of Conduct.









                       

                      draft saved


                      draft discarded


















                      J Faucher is a new contributor. Be nice, and check out our Code of Conduct.












                      J Faucher is a new contributor. Be nice, and check out our Code of Conduct.











                      J Faucher is a new contributor. Be nice, and check out our Code of Conduct.













                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53109888%2fhow-to-create-a-spacer-in-the-c-class-memory-structure%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Bahrain

                      Postfix configuration issue with fips on centos 7; mailgun relay