Memory usage: #define vs. static const for uint8_t

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












4















I'm writing an Arduino library to communicate with an I2C device, and I'm wondering what the best way is to declare all the register addresses so as to save memory.



Using #defines:



#define REGISTER_MOTOR_1_MODE 0x44
#define REGISTER_MOTOR_2_MODE 0x47


Or using static const:



static const uint8_t REGISTER_MOTOR_1_MODE = 0x44;
static const uint8_t REGISTER_MOTOR_2_MODE = 0x47;


(Obviously I have more than just two registers I need to declare, but I thought two would illustrate the point just fine)










share|improve this question






















  • define's are just "find and replace"s, and can bit you, if you do anything other than numbers. For example #define LED_MASK 0x01<<2. A safe(r) way to write that would be #define LED_MASK (0x01<<2). See also stackoverflow.com/questions/6542270/…

    – Gerben
    Feb 25 at 16:24















4















I'm writing an Arduino library to communicate with an I2C device, and I'm wondering what the best way is to declare all the register addresses so as to save memory.



Using #defines:



#define REGISTER_MOTOR_1_MODE 0x44
#define REGISTER_MOTOR_2_MODE 0x47


Or using static const:



static const uint8_t REGISTER_MOTOR_1_MODE = 0x44;
static const uint8_t REGISTER_MOTOR_2_MODE = 0x47;


(Obviously I have more than just two registers I need to declare, but I thought two would illustrate the point just fine)










share|improve this question






















  • define's are just "find and replace"s, and can bit you, if you do anything other than numbers. For example #define LED_MASK 0x01<<2. A safe(r) way to write that would be #define LED_MASK (0x01<<2). See also stackoverflow.com/questions/6542270/…

    – Gerben
    Feb 25 at 16:24













4












4








4


1






I'm writing an Arduino library to communicate with an I2C device, and I'm wondering what the best way is to declare all the register addresses so as to save memory.



Using #defines:



#define REGISTER_MOTOR_1_MODE 0x44
#define REGISTER_MOTOR_2_MODE 0x47


Or using static const:



static const uint8_t REGISTER_MOTOR_1_MODE = 0x44;
static const uint8_t REGISTER_MOTOR_2_MODE = 0x47;


(Obviously I have more than just two registers I need to declare, but I thought two would illustrate the point just fine)










share|improve this question














I'm writing an Arduino library to communicate with an I2C device, and I'm wondering what the best way is to declare all the register addresses so as to save memory.



Using #defines:



#define REGISTER_MOTOR_1_MODE 0x44
#define REGISTER_MOTOR_2_MODE 0x47


Or using static const:



static const uint8_t REGISTER_MOTOR_1_MODE = 0x44;
static const uint8_t REGISTER_MOTOR_2_MODE = 0x47;


(Obviously I have more than just two registers I need to declare, but I thought two would illustrate the point just fine)







c++ memory-usage






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 25 at 14:40









Android DevAndroid Dev

1234




1234












  • define's are just "find and replace"s, and can bit you, if you do anything other than numbers. For example #define LED_MASK 0x01<<2. A safe(r) way to write that would be #define LED_MASK (0x01<<2). See also stackoverflow.com/questions/6542270/…

    – Gerben
    Feb 25 at 16:24

















  • define's are just "find and replace"s, and can bit you, if you do anything other than numbers. For example #define LED_MASK 0x01<<2. A safe(r) way to write that would be #define LED_MASK (0x01<<2). See also stackoverflow.com/questions/6542270/…

    – Gerben
    Feb 25 at 16:24
















define's are just "find and replace"s, and can bit you, if you do anything other than numbers. For example #define LED_MASK 0x01<<2. A safe(r) way to write that would be #define LED_MASK (0x01<<2). See also stackoverflow.com/questions/6542270/…

– Gerben
Feb 25 at 16:24





define's are just "find and replace"s, and can bit you, if you do anything other than numbers. For example #define LED_MASK 0x01<<2. A safe(r) way to write that would be #define LED_MASK (0x01<<2). See also stackoverflow.com/questions/6542270/…

– Gerben
Feb 25 at 16:24










3 Answers
3






active

oldest

votes


















8














You'll find no noticeable difference memory-wise between the two.



The only real difference is that the const method also imposes a type to the value, which can be useful for function overloading or mathematical operations.






share|improve this answer























  • Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

    – Pharap
    Feb 26 at 5:34











  • @Pharap Almost... Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

    – Majenko
    Feb 26 at 10:10











  • The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

    – Pharap
    Feb 27 at 6:19


















5














A #define is a preprocessor macro. As Gerben says in his comment, it's just an automated find-and-replace.



If you use it to hold things like C string constants, e.g. #define ERROR_STRING "You messed up, bud!" it could actually cause your program to take more memory, since that same string literal will be duplicated every time you reference it. In that case a static const would be both type-safe AND reduce memory usage.






share|improve this answer























  • Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

    – juhist
    Feb 25 at 19:03






  • 2





    @juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not. Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

    – Mooing Duck
    Feb 25 at 19:34











  • @MooingDuck I compiled a program having many std::printf("%pn", "foo"); lines in it. All of them print the same address.

    – juhist
    Feb 25 at 20:55











  • @MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

    – supercat
    Feb 25 at 21:01






  • 1





    @juhist: Sure. In your compiler and your compiler flags. With my compiler and my flags, I get different addresses.

    – Mooing Duck
    Feb 25 at 21:39


















3














Theoretically both approaches should consume the same amount of space and will probably result in the same code.




However, rather than that meaning "pick any one", what that actually means is that you should turn your attention to other factors when deciding which one to use.



As a rule of thumb you should generally avoid macros because they don't respect scoping rules due to how they work.

This can lead to some serious problems in certain cases.

See Why are preprocessor macros evil and what are the alternatives?.




However, I'd like to point out a third option: constexpr.



constexpr uint8_t motorMode1Register = 0x44;


constexpr implies const and is a better expression of the intent that the value should be capable of being evaluated at compile time.
constexpr literally means "this is a constant expression and thus can be evaluated at compile time".

As a result of this, constexpr variables can be used in situations where other variables cannot, such as template parameters.



See Constexpr vs Macros.






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("schematics", function ()
    StackExchange.schematics.init();
    );
    , "cicuitlab");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "540"
    ;
    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',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    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
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f61970%2fmemory-usage-define-vs-static-const-for-uint8-t%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    You'll find no noticeable difference memory-wise between the two.



    The only real difference is that the const method also imposes a type to the value, which can be useful for function overloading or mathematical operations.






    share|improve this answer























    • Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

      – Pharap
      Feb 26 at 5:34











    • @Pharap Almost... Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

      – Majenko
      Feb 26 at 10:10











    • The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

      – Pharap
      Feb 27 at 6:19















    8














    You'll find no noticeable difference memory-wise between the two.



    The only real difference is that the const method also imposes a type to the value, which can be useful for function overloading or mathematical operations.






    share|improve this answer























    • Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

      – Pharap
      Feb 26 at 5:34











    • @Pharap Almost... Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

      – Majenko
      Feb 26 at 10:10











    • The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

      – Pharap
      Feb 27 at 6:19













    8












    8








    8







    You'll find no noticeable difference memory-wise between the two.



    The only real difference is that the const method also imposes a type to the value, which can be useful for function overloading or mathematical operations.






    share|improve this answer













    You'll find no noticeable difference memory-wise between the two.



    The only real difference is that the const method also imposes a type to the value, which can be useful for function overloading or mathematical operations.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Feb 25 at 14:42









    MajenkoMajenko

    68.9k43277




    68.9k43277












    • Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

      – Pharap
      Feb 26 at 5:34











    • @Pharap Almost... Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

      – Majenko
      Feb 26 at 10:10











    • The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

      – Pharap
      Feb 27 at 6:19

















    • Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

      – Pharap
      Feb 26 at 5:34











    • @Pharap Almost... Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

      – Majenko
      Feb 26 at 10:10











    • The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

      – Pharap
      Feb 27 at 6:19
















    Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

    – Pharap
    Feb 26 at 5:34





    Macros also have types. #define REGISTER_MOTOR_1_MODE 0x44 would cause REGISTER_MOTOR_1_MODE to have a type of int. The difference is more in the explicitness of the type.

    – Pharap
    Feb 26 at 5:34













    @Pharap Almost... Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

    – Majenko
    Feb 26 at 10:10





    @Pharap Almost... Macros do not have a type. However, the content of the macro can have either an implicit or explicit type. That type is nothing to do with the macro.

    – Majenko
    Feb 26 at 10:10













    The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

    – Pharap
    Feb 27 at 6:19





    The type of the expression that the macro substitutes for is for all intents and purposes the type of the macro. Unless the macro accepts arguments then the expression will always have the same type. You can stick a macro in a decltype and get a valid type. Strictly yes, the macro is gone by the time the actual compilation phase begins, and yes, not all macros will substitute for a valid expression with a type, but the point is that if you put a macro into the code and that macro substitutes for a valid expression then the resulting value won't be 'untyped'.

    – Pharap
    Feb 27 at 6:19











    5














    A #define is a preprocessor macro. As Gerben says in his comment, it's just an automated find-and-replace.



    If you use it to hold things like C string constants, e.g. #define ERROR_STRING "You messed up, bud!" it could actually cause your program to take more memory, since that same string literal will be duplicated every time you reference it. In that case a static const would be both type-safe AND reduce memory usage.






    share|improve this answer























    • Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

      – juhist
      Feb 25 at 19:03






    • 2





      @juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not. Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

      – Mooing Duck
      Feb 25 at 19:34











    • @MooingDuck I compiled a program having many std::printf("%pn", "foo"); lines in it. All of them print the same address.

      – juhist
      Feb 25 at 20:55











    • @MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

      – supercat
      Feb 25 at 21:01






    • 1





      @juhist: Sure. In your compiler and your compiler flags. With my compiler and my flags, I get different addresses.

      – Mooing Duck
      Feb 25 at 21:39















    5














    A #define is a preprocessor macro. As Gerben says in his comment, it's just an automated find-and-replace.



    If you use it to hold things like C string constants, e.g. #define ERROR_STRING "You messed up, bud!" it could actually cause your program to take more memory, since that same string literal will be duplicated every time you reference it. In that case a static const would be both type-safe AND reduce memory usage.






    share|improve this answer























    • Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

      – juhist
      Feb 25 at 19:03






    • 2





      @juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not. Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

      – Mooing Duck
      Feb 25 at 19:34











    • @MooingDuck I compiled a program having many std::printf("%pn", "foo"); lines in it. All of them print the same address.

      – juhist
      Feb 25 at 20:55











    • @MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

      – supercat
      Feb 25 at 21:01






    • 1





      @juhist: Sure. In your compiler and your compiler flags. With my compiler and my flags, I get different addresses.

      – Mooing Duck
      Feb 25 at 21:39













    5












    5








    5







    A #define is a preprocessor macro. As Gerben says in his comment, it's just an automated find-and-replace.



    If you use it to hold things like C string constants, e.g. #define ERROR_STRING "You messed up, bud!" it could actually cause your program to take more memory, since that same string literal will be duplicated every time you reference it. In that case a static const would be both type-safe AND reduce memory usage.






    share|improve this answer













    A #define is a preprocessor macro. As Gerben says in his comment, it's just an automated find-and-replace.



    If you use it to hold things like C string constants, e.g. #define ERROR_STRING "You messed up, bud!" it could actually cause your program to take more memory, since that same string literal will be duplicated every time you reference it. In that case a static const would be both type-safe AND reduce memory usage.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Feb 25 at 16:45









    Duncan CDuncan C

    1,9021618




    1,9021618












    • Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

      – juhist
      Feb 25 at 19:03






    • 2





      @juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not. Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

      – Mooing Duck
      Feb 25 at 19:34











    • @MooingDuck I compiled a program having many std::printf("%pn", "foo"); lines in it. All of them print the same address.

      – juhist
      Feb 25 at 20:55











    • @MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

      – supercat
      Feb 25 at 21:01






    • 1





      @juhist: Sure. In your compiler and your compiler flags. With my compiler and my flags, I get different addresses.

      – Mooing Duck
      Feb 25 at 21:39

















    • Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

      – juhist
      Feb 25 at 19:03






    • 2





      @juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not. Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

      – Mooing Duck
      Feb 25 at 19:34











    • @MooingDuck I compiled a program having many std::printf("%pn", "foo"); lines in it. All of them print the same address.

      – juhist
      Feb 25 at 20:55











    • @MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

      – supercat
      Feb 25 at 21:01






    • 1





      @juhist: Sure. In your compiler and your compiler flags. With my compiler and my flags, I get different addresses.

      – Mooing Duck
      Feb 25 at 21:39
















    Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

    – juhist
    Feb 25 at 19:03





    Would it be duplicated? I mean, isn't it the job of the compiler to ensure "You messed up, bud!" occurs exactly once in the string constant table?

    – juhist
    Feb 25 at 19:03




    2




    2





    @juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not. Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

    – Mooing Duck
    Feb 25 at 19:34





    @juhist: C++ explicitly states that the compiler can choose to duplicate identical strings, or not. Most compilers have a flag to either do this, or not. I think, by default, most compilers do not merge strings, in case the app relies on them being unique.

    – Mooing Duck
    Feb 25 at 19:34













    @MooingDuck I compiled a program having many std::printf("%pn", "foo"); lines in it. All of them print the same address.

    – juhist
    Feb 25 at 20:55





    @MooingDuck I compiled a program having many std::printf("%pn", "foo"); lines in it. All of them print the same address.

    – juhist
    Feb 25 at 20:55













    @MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

    – supercat
    Feb 25 at 21:01





    @MooingDuck: While few compilers will guarantee that strings will always be merged, I think the normal reason is that upholding such a guarantee may impose extra build-time costs and complexity, and the savings in storage from merging strings may or may not be worthwhile.

    – supercat
    Feb 25 at 21:01




    1




    1





    @juhist: Sure. In your compiler and your compiler flags. With my compiler and my flags, I get different addresses.

    – Mooing Duck
    Feb 25 at 21:39





    @juhist: Sure. In your compiler and your compiler flags. With my compiler and my flags, I get different addresses.

    – Mooing Duck
    Feb 25 at 21:39











    3














    Theoretically both approaches should consume the same amount of space and will probably result in the same code.




    However, rather than that meaning "pick any one", what that actually means is that you should turn your attention to other factors when deciding which one to use.



    As a rule of thumb you should generally avoid macros because they don't respect scoping rules due to how they work.

    This can lead to some serious problems in certain cases.

    See Why are preprocessor macros evil and what are the alternatives?.




    However, I'd like to point out a third option: constexpr.



    constexpr uint8_t motorMode1Register = 0x44;


    constexpr implies const and is a better expression of the intent that the value should be capable of being evaluated at compile time.
    constexpr literally means "this is a constant expression and thus can be evaluated at compile time".

    As a result of this, constexpr variables can be used in situations where other variables cannot, such as template parameters.



    See Constexpr vs Macros.






    share|improve this answer



























      3














      Theoretically both approaches should consume the same amount of space and will probably result in the same code.




      However, rather than that meaning "pick any one", what that actually means is that you should turn your attention to other factors when deciding which one to use.



      As a rule of thumb you should generally avoid macros because they don't respect scoping rules due to how they work.

      This can lead to some serious problems in certain cases.

      See Why are preprocessor macros evil and what are the alternatives?.




      However, I'd like to point out a third option: constexpr.



      constexpr uint8_t motorMode1Register = 0x44;


      constexpr implies const and is a better expression of the intent that the value should be capable of being evaluated at compile time.
      constexpr literally means "this is a constant expression and thus can be evaluated at compile time".

      As a result of this, constexpr variables can be used in situations where other variables cannot, such as template parameters.



      See Constexpr vs Macros.






      share|improve this answer

























        3












        3








        3







        Theoretically both approaches should consume the same amount of space and will probably result in the same code.




        However, rather than that meaning "pick any one", what that actually means is that you should turn your attention to other factors when deciding which one to use.



        As a rule of thumb you should generally avoid macros because they don't respect scoping rules due to how they work.

        This can lead to some serious problems in certain cases.

        See Why are preprocessor macros evil and what are the alternatives?.




        However, I'd like to point out a third option: constexpr.



        constexpr uint8_t motorMode1Register = 0x44;


        constexpr implies const and is a better expression of the intent that the value should be capable of being evaluated at compile time.
        constexpr literally means "this is a constant expression and thus can be evaluated at compile time".

        As a result of this, constexpr variables can be used in situations where other variables cannot, such as template parameters.



        See Constexpr vs Macros.






        share|improve this answer













        Theoretically both approaches should consume the same amount of space and will probably result in the same code.




        However, rather than that meaning "pick any one", what that actually means is that you should turn your attention to other factors when deciding which one to use.



        As a rule of thumb you should generally avoid macros because they don't respect scoping rules due to how they work.

        This can lead to some serious problems in certain cases.

        See Why are preprocessor macros evil and what are the alternatives?.




        However, I'd like to point out a third option: constexpr.



        constexpr uint8_t motorMode1Register = 0x44;


        constexpr implies const and is a better expression of the intent that the value should be capable of being evaluated at compile time.
        constexpr literally means "this is a constant expression and thus can be evaluated at compile time".

        As a result of this, constexpr variables can be used in situations where other variables cannot, such as template parameters.



        See Constexpr vs Macros.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 26 at 5:42









        PharapPharap

        1498




        1498



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Arduino Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f61970%2fmemory-usage-define-vs-static-const-for-uint8-t%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            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