call function in struct initialization












2















Consider the following snippet:



struct my_struct {
int a;
int b;
int c;
};


void my_func(unsigned long x)
{
struct my_struct m = {
{ 0, 1, 2 },
{ 11, 22, htonl(x) },
{ 0x1, 0xa, 0xbb }
};
...
}


Is it legal/portable to call a function inside of a structure initialization block?










share|improve this question























  • Do you mean in general or just for automatic variables as in your snippet? What does your standard compliant compiler say? What do you expect? Why?

    – too honest for this site
    Nov 24 '18 at 1:39













  • This compiles cleanly [under gcc] as you've presented it. However, if you made m a global (file scope variable), it will not. The compiler flags htonl: error: initializer element is not constant. I believe most C compilers will behave in a similar manner. Side note: C++ does allow this at global scope [in your example, it warns about ntonl being unsigned vs the signed int c, but this would be easy enough to fix]

    – Craig Estey
    Nov 24 '18 at 1:52


















2















Consider the following snippet:



struct my_struct {
int a;
int b;
int c;
};


void my_func(unsigned long x)
{
struct my_struct m = {
{ 0, 1, 2 },
{ 11, 22, htonl(x) },
{ 0x1, 0xa, 0xbb }
};
...
}


Is it legal/portable to call a function inside of a structure initialization block?










share|improve this question























  • Do you mean in general or just for automatic variables as in your snippet? What does your standard compliant compiler say? What do you expect? Why?

    – too honest for this site
    Nov 24 '18 at 1:39













  • This compiles cleanly [under gcc] as you've presented it. However, if you made m a global (file scope variable), it will not. The compiler flags htonl: error: initializer element is not constant. I believe most C compilers will behave in a similar manner. Side note: C++ does allow this at global scope [in your example, it warns about ntonl being unsigned vs the signed int c, but this would be easy enough to fix]

    – Craig Estey
    Nov 24 '18 at 1:52
















2












2








2








Consider the following snippet:



struct my_struct {
int a;
int b;
int c;
};


void my_func(unsigned long x)
{
struct my_struct m = {
{ 0, 1, 2 },
{ 11, 22, htonl(x) },
{ 0x1, 0xa, 0xbb }
};
...
}


Is it legal/portable to call a function inside of a structure initialization block?










share|improve this question














Consider the following snippet:



struct my_struct {
int a;
int b;
int c;
};


void my_func(unsigned long x)
{
struct my_struct m = {
{ 0, 1, 2 },
{ 11, 22, htonl(x) },
{ 0x1, 0xa, 0xbb }
};
...
}


Is it legal/portable to call a function inside of a structure initialization block?







c function struct






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 24 '18 at 1:16









MarkMark

1,68242658




1,68242658













  • Do you mean in general or just for automatic variables as in your snippet? What does your standard compliant compiler say? What do you expect? Why?

    – too honest for this site
    Nov 24 '18 at 1:39













  • This compiles cleanly [under gcc] as you've presented it. However, if you made m a global (file scope variable), it will not. The compiler flags htonl: error: initializer element is not constant. I believe most C compilers will behave in a similar manner. Side note: C++ does allow this at global scope [in your example, it warns about ntonl being unsigned vs the signed int c, but this would be easy enough to fix]

    – Craig Estey
    Nov 24 '18 at 1:52





















  • Do you mean in general or just for automatic variables as in your snippet? What does your standard compliant compiler say? What do you expect? Why?

    – too honest for this site
    Nov 24 '18 at 1:39













  • This compiles cleanly [under gcc] as you've presented it. However, if you made m a global (file scope variable), it will not. The compiler flags htonl: error: initializer element is not constant. I believe most C compilers will behave in a similar manner. Side note: C++ does allow this at global scope [in your example, it warns about ntonl being unsigned vs the signed int c, but this would be easy enough to fix]

    – Craig Estey
    Nov 24 '18 at 1:52



















Do you mean in general or just for automatic variables as in your snippet? What does your standard compliant compiler say? What do you expect? Why?

– too honest for this site
Nov 24 '18 at 1:39







Do you mean in general or just for automatic variables as in your snippet? What does your standard compliant compiler say? What do you expect? Why?

– too honest for this site
Nov 24 '18 at 1:39















This compiles cleanly [under gcc] as you've presented it. However, if you made m a global (file scope variable), it will not. The compiler flags htonl: error: initializer element is not constant. I believe most C compilers will behave in a similar manner. Side note: C++ does allow this at global scope [in your example, it warns about ntonl being unsigned vs the signed int c, but this would be easy enough to fix]

– Craig Estey
Nov 24 '18 at 1:52







This compiles cleanly [under gcc] as you've presented it. However, if you made m a global (file scope variable), it will not. The compiler flags htonl: error: initializer element is not constant. I believe most C compilers will behave in a similar manner. Side note: C++ does allow this at global scope [in your example, it warns about ntonl being unsigned vs the signed int c, but this would be easy enough to fix]

– Craig Estey
Nov 24 '18 at 1:52














2 Answers
2






active

oldest

votes


















2















Is it legal/portable to call a function inside of a structure initialization block?




Initialization ($6.7.8/1)




[...]



|     initializer-list:
| designationopt initializer
| initializer-list , designationopt initializer



~> initializer-lists consist of initializers



Initialization ($6.7.8/4)




All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals




~> Initializers consist of expressions. (constant-expr. for objects with static storage duration)



Expressions (§6.5/1):




An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.




~> A function call is an expression.






share|improve this answer





















  • 1





    We be sticking to the code...

    – David C. Rankin
    Nov 24 '18 at 2:20











  • @DavidC.Rankin Sorry, what do you mean?

    – Swordfish
    Nov 24 '18 at 2:22











  • Sorry, that's the funny line for "Pirates of the Caribbean" that fit with the good cites to the "code".

    – David C. Rankin
    Nov 24 '18 at 2:36











  • @DavidC.Rankin oh, legal-code. Now I get it. Yes, I'm a lawyer at heart ;)

    – Swordfish
    Nov 24 '18 at 2:41



















4














Yes, it is legal, as long as you are initializing an object with automatic storage duration (as in your example). For objects with static storage duration that would not be legal, since such objects allow only constant expressions in their initializers.



Also keep in mind though that in C evaluations of initializer expressions are indeterminately sequenced with respect to one another. Which means that if you have multiple function calls among your initializers and these functions' results depend on some shared state, these initalizers might behave unpredictably



int foo()
{
static int a;
return ++a;
}

int main()
{
struct { int x, y; } s = { foo(), foo() };
/* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
}


With regard to portability, one can note that C89/90 did not permit this (formally in C89/90 all {}-enclosed initializers has to be constant expressions, even for automatic objects), but most popular C89/90 compilers supported this regardless.






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',
    autoActivateHeartbeat: false,
    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
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53454371%2fcall-function-in-struct-initialization%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2















    Is it legal/portable to call a function inside of a structure initialization block?




    Initialization ($6.7.8/1)




    [...]



    |     initializer-list:
    | designationopt initializer
    | initializer-list , designationopt initializer



    ~> initializer-lists consist of initializers



    Initialization ($6.7.8/4)




    All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals




    ~> Initializers consist of expressions. (constant-expr. for objects with static storage duration)



    Expressions (§6.5/1):




    An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.




    ~> A function call is an expression.






    share|improve this answer





















    • 1





      We be sticking to the code...

      – David C. Rankin
      Nov 24 '18 at 2:20











    • @DavidC.Rankin Sorry, what do you mean?

      – Swordfish
      Nov 24 '18 at 2:22











    • Sorry, that's the funny line for "Pirates of the Caribbean" that fit with the good cites to the "code".

      – David C. Rankin
      Nov 24 '18 at 2:36











    • @DavidC.Rankin oh, legal-code. Now I get it. Yes, I'm a lawyer at heart ;)

      – Swordfish
      Nov 24 '18 at 2:41
















    2















    Is it legal/portable to call a function inside of a structure initialization block?




    Initialization ($6.7.8/1)




    [...]



    |     initializer-list:
    | designationopt initializer
    | initializer-list , designationopt initializer



    ~> initializer-lists consist of initializers



    Initialization ($6.7.8/4)




    All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals




    ~> Initializers consist of expressions. (constant-expr. for objects with static storage duration)



    Expressions (§6.5/1):




    An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.




    ~> A function call is an expression.






    share|improve this answer





















    • 1





      We be sticking to the code...

      – David C. Rankin
      Nov 24 '18 at 2:20











    • @DavidC.Rankin Sorry, what do you mean?

      – Swordfish
      Nov 24 '18 at 2:22











    • Sorry, that's the funny line for "Pirates of the Caribbean" that fit with the good cites to the "code".

      – David C. Rankin
      Nov 24 '18 at 2:36











    • @DavidC.Rankin oh, legal-code. Now I get it. Yes, I'm a lawyer at heart ;)

      – Swordfish
      Nov 24 '18 at 2:41














    2












    2








    2








    Is it legal/portable to call a function inside of a structure initialization block?




    Initialization ($6.7.8/1)




    [...]



    |     initializer-list:
    | designationopt initializer
    | initializer-list , designationopt initializer



    ~> initializer-lists consist of initializers



    Initialization ($6.7.8/4)




    All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals




    ~> Initializers consist of expressions. (constant-expr. for objects with static storage duration)



    Expressions (§6.5/1):




    An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.




    ~> A function call is an expression.






    share|improve this answer
















    Is it legal/portable to call a function inside of a structure initialization block?




    Initialization ($6.7.8/1)




    [...]



    |     initializer-list:
    | designationopt initializer
    | initializer-list , designationopt initializer



    ~> initializer-lists consist of initializers



    Initialization ($6.7.8/4)




    All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals




    ~> Initializers consist of expressions. (constant-expr. for objects with static storage duration)



    Expressions (§6.5/1):




    An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.




    ~> A function call is an expression.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 24 '18 at 2:24

























    answered Nov 24 '18 at 2:02









    SwordfishSwordfish

    9,05211335




    9,05211335








    • 1





      We be sticking to the code...

      – David C. Rankin
      Nov 24 '18 at 2:20











    • @DavidC.Rankin Sorry, what do you mean?

      – Swordfish
      Nov 24 '18 at 2:22











    • Sorry, that's the funny line for "Pirates of the Caribbean" that fit with the good cites to the "code".

      – David C. Rankin
      Nov 24 '18 at 2:36











    • @DavidC.Rankin oh, legal-code. Now I get it. Yes, I'm a lawyer at heart ;)

      – Swordfish
      Nov 24 '18 at 2:41














    • 1





      We be sticking to the code...

      – David C. Rankin
      Nov 24 '18 at 2:20











    • @DavidC.Rankin Sorry, what do you mean?

      – Swordfish
      Nov 24 '18 at 2:22











    • Sorry, that's the funny line for "Pirates of the Caribbean" that fit with the good cites to the "code".

      – David C. Rankin
      Nov 24 '18 at 2:36











    • @DavidC.Rankin oh, legal-code. Now I get it. Yes, I'm a lawyer at heart ;)

      – Swordfish
      Nov 24 '18 at 2:41








    1




    1





    We be sticking to the code...

    – David C. Rankin
    Nov 24 '18 at 2:20





    We be sticking to the code...

    – David C. Rankin
    Nov 24 '18 at 2:20













    @DavidC.Rankin Sorry, what do you mean?

    – Swordfish
    Nov 24 '18 at 2:22





    @DavidC.Rankin Sorry, what do you mean?

    – Swordfish
    Nov 24 '18 at 2:22













    Sorry, that's the funny line for "Pirates of the Caribbean" that fit with the good cites to the "code".

    – David C. Rankin
    Nov 24 '18 at 2:36





    Sorry, that's the funny line for "Pirates of the Caribbean" that fit with the good cites to the "code".

    – David C. Rankin
    Nov 24 '18 at 2:36













    @DavidC.Rankin oh, legal-code. Now I get it. Yes, I'm a lawyer at heart ;)

    – Swordfish
    Nov 24 '18 at 2:41





    @DavidC.Rankin oh, legal-code. Now I get it. Yes, I'm a lawyer at heart ;)

    – Swordfish
    Nov 24 '18 at 2:41













    4














    Yes, it is legal, as long as you are initializing an object with automatic storage duration (as in your example). For objects with static storage duration that would not be legal, since such objects allow only constant expressions in their initializers.



    Also keep in mind though that in C evaluations of initializer expressions are indeterminately sequenced with respect to one another. Which means that if you have multiple function calls among your initializers and these functions' results depend on some shared state, these initalizers might behave unpredictably



    int foo()
    {
    static int a;
    return ++a;
    }

    int main()
    {
    struct { int x, y; } s = { foo(), foo() };
    /* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
    }


    With regard to portability, one can note that C89/90 did not permit this (formally in C89/90 all {}-enclosed initializers has to be constant expressions, even for automatic objects), but most popular C89/90 compilers supported this regardless.






    share|improve this answer






























      4














      Yes, it is legal, as long as you are initializing an object with automatic storage duration (as in your example). For objects with static storage duration that would not be legal, since such objects allow only constant expressions in their initializers.



      Also keep in mind though that in C evaluations of initializer expressions are indeterminately sequenced with respect to one another. Which means that if you have multiple function calls among your initializers and these functions' results depend on some shared state, these initalizers might behave unpredictably



      int foo()
      {
      static int a;
      return ++a;
      }

      int main()
      {
      struct { int x, y; } s = { foo(), foo() };
      /* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
      }


      With regard to portability, one can note that C89/90 did not permit this (formally in C89/90 all {}-enclosed initializers has to be constant expressions, even for automatic objects), but most popular C89/90 compilers supported this regardless.






      share|improve this answer




























        4












        4








        4







        Yes, it is legal, as long as you are initializing an object with automatic storage duration (as in your example). For objects with static storage duration that would not be legal, since such objects allow only constant expressions in their initializers.



        Also keep in mind though that in C evaluations of initializer expressions are indeterminately sequenced with respect to one another. Which means that if you have multiple function calls among your initializers and these functions' results depend on some shared state, these initalizers might behave unpredictably



        int foo()
        {
        static int a;
        return ++a;
        }

        int main()
        {
        struct { int x, y; } s = { foo(), foo() };
        /* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
        }


        With regard to portability, one can note that C89/90 did not permit this (formally in C89/90 all {}-enclosed initializers has to be constant expressions, even for automatic objects), but most popular C89/90 compilers supported this regardless.






        share|improve this answer















        Yes, it is legal, as long as you are initializing an object with automatic storage duration (as in your example). For objects with static storage duration that would not be legal, since such objects allow only constant expressions in their initializers.



        Also keep in mind though that in C evaluations of initializer expressions are indeterminately sequenced with respect to one another. Which means that if you have multiple function calls among your initializers and these functions' results depend on some shared state, these initalizers might behave unpredictably



        int foo()
        {
        static int a;
        return ++a;
        }

        int main()
        {
        struct { int x, y; } s = { foo(), foo() };
        /* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
        }


        With regard to portability, one can note that C89/90 did not permit this (formally in C89/90 all {}-enclosed initializers has to be constant expressions, even for automatic objects), but most popular C89/90 compilers supported this regardless.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 24 '18 at 4:35

























        answered Nov 24 '18 at 2:04









        AnTAnT

        258k32411655




        258k32411655






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • 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%2fstackoverflow.com%2fquestions%2f53454371%2fcall-function-in-struct-initialization%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

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)