Is this type punning well defined?












7















I have structure like below.



struct result{
int a;
int b;
int c;
int d;
}


and union like below.



union convert{
int arr[4];
struct result res;
}


and I type pun as below.



  int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?

printf("%d %dn", pointer->res.a, pointer->res.b);









share|improve this question

























  • @StoryTeller I'm sorry, it typing mistake.

    – KBlr
    3 hours ago






  • 2





    Id you can assure no paddign in the structure - it is safe at list with gcc

    – P__J__
    3 hours ago











  • @AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?

    – Bathsheba
    3 hours ago






  • 1





    @Bathsheba: Darn me and me illiteracy

    – AndyG
    3 hours ago











  • Hmmm, If static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm"); was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.

    – chux
    1 hour ago
















7















I have structure like below.



struct result{
int a;
int b;
int c;
int d;
}


and union like below.



union convert{
int arr[4];
struct result res;
}


and I type pun as below.



  int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?

printf("%d %dn", pointer->res.a, pointer->res.b);









share|improve this question

























  • @StoryTeller I'm sorry, it typing mistake.

    – KBlr
    3 hours ago






  • 2





    Id you can assure no paddign in the structure - it is safe at list with gcc

    – P__J__
    3 hours ago











  • @AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?

    – Bathsheba
    3 hours ago






  • 1





    @Bathsheba: Darn me and me illiteracy

    – AndyG
    3 hours ago











  • Hmmm, If static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm"); was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.

    – chux
    1 hour ago














7












7








7








I have structure like below.



struct result{
int a;
int b;
int c;
int d;
}


and union like below.



union convert{
int arr[4];
struct result res;
}


and I type pun as below.



  int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?

printf("%d %dn", pointer->res.a, pointer->res.b);









share|improve this question
















I have structure like below.



struct result{
int a;
int b;
int c;
int d;
}


and union like below.



union convert{
int arr[4];
struct result res;
}


and I type pun as below.



  int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?

printf("%d %dn", pointer->res.a, pointer->res.b);






c language-lawyer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









AndyG

26.2k76995




26.2k76995










asked 3 hours ago









KBlrKBlr

1498




1498













  • @StoryTeller I'm sorry, it typing mistake.

    – KBlr
    3 hours ago






  • 2





    Id you can assure no paddign in the structure - it is safe at list with gcc

    – P__J__
    3 hours ago











  • @AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?

    – Bathsheba
    3 hours ago






  • 1





    @Bathsheba: Darn me and me illiteracy

    – AndyG
    3 hours ago











  • Hmmm, If static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm"); was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.

    – chux
    1 hour ago



















  • @StoryTeller I'm sorry, it typing mistake.

    – KBlr
    3 hours ago






  • 2





    Id you can assure no paddign in the structure - it is safe at list with gcc

    – P__J__
    3 hours ago











  • @AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?

    – Bathsheba
    3 hours ago






  • 1





    @Bathsheba: Darn me and me illiteracy

    – AndyG
    3 hours ago











  • Hmmm, If static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm"); was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.

    – chux
    1 hour ago

















@StoryTeller I'm sorry, it typing mistake.

– KBlr
3 hours ago





@StoryTeller I'm sorry, it typing mistake.

– KBlr
3 hours ago




2




2





Id you can assure no paddign in the structure - it is safe at list with gcc

– P__J__
3 hours ago





Id you can assure no paddign in the structure - it is safe at list with gcc

– P__J__
3 hours ago













@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?

– Bathsheba
3 hours ago





@AndyG; You're correct on the first point, but on the second, doesn't {1,2,3,5} initialise the array?

– Bathsheba
3 hours ago




1




1





@Bathsheba: Darn me and me illiteracy

– AndyG
3 hours ago





@Bathsheba: Darn me and me illiteracy

– AndyG
3 hours ago













Hmmm, If static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm"); was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.

– chux
1 hour ago





Hmmm, If static_assert(sizeof(convert.arr) == sizeof(convert.res), "Hmmm"); was added, I think the concern about padding is gone - Code would simply not compile when padding occurred.

– chux
1 hour ago












5 Answers
5






active

oldest

votes


















5














pointer->res.a is fine but the behaviour of pointer->res.b is undefined.



There could be an arbitrary amount of padding between the a and b members.



Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.






share|improve this answer
























  • Thank you! If I ensure that there will be no padding is it then well defined?

    – KBlr
    3 hours ago











  • @KBlr: Yep! Just not portable

    – AndyG
    3 hours ago






  • 2





    pointer->res.a accesses an object (arr1) through an lvalue (pointer->res) in violation of C 2018 6.5 7.

    – Eric Postpischil
    1 hour ago













  • @EricPostpischil one could say that the arr1[0] (because arr1 is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a, which does not violate 6.5.7, because the type of the lvalue is int and the accessed object's type is int.

    – Language Lawyer
    1 hour ago



















2














C imposes no rule about how much padding is left between 2 consecutive members of a structure.



This is why the implementations define many #pragma directives -- specially to change this behaviour.



So, as the answer of Bathsheba says, ...->b is undefined.



I answered the very same question some time ago, here.






share|improve this answer

































    1















    Is this type punning well defined?




    struct result{
    int a,b,c,d;
    }

    union convert {
    int arr[4];
    struct result res;
    }

    int arr1[4] = {1,2,3,5};
    union convert *pointer = (union convert *) arr1;


    (union convert *) arr1 risks alignment failure.




    A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8




    There is no requirement that union convert and int share the same alignment. union convert requirements may exceed int for example.



    Consider this possibility: arr1 lives on int street where all addresses are multiple of 4. union and struct friends lives on "multiple of 8" street. arr1 might have address 0x1004 (not a multiple of 8).



    This type punning is not well defined.






    share|improve this answer


























    • What if I add __attribute__((packed)) to structure ?

      – kiran Biradar
      21 secs ago



















    0














    Pointer punning is not safe. Use real union punning instead.



    Assumptions: the struct is properly packed (no padding between the members)



    #include <stdio.h>
    #include <string.h>



    struct __attribute__((packed)) result{
    int a;
    int b;
    int c;
    int d;
    };

    union convert{
    int arr[4];
    struct result res;
    };

    volatile int arr1[4];

    void foo(void)
    {

    union convert cnv;

    memcpy(&cnv, (void *)arr1, sizeof(arr1));

    printf("%d %dn", cnv.res.a, cnv.res.b);
    }


    all modern compilers will optimize out the memcpy call



    https://godbolt.org/z/4qtRIF



    .LC0:
    .string "%d %dn"
    foo:
    mov rsi, QWORD PTR arr1[rip]
    xor eax, eax
    mov rdi, QWORD PTR arr1[rip+8]
    mov edi, OFFSET FLAT:.LC0
    mov rdx, rsi
    sar rdx, 32
    jmp printf





    share|improve this answer
























    • Agree. Deleted.

      – Language Lawyer
      18 mins ago



















    0














    After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator -> semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):




    A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.




    means that a postfix expression followed by the -> operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert.






    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%2f54237976%2fis-this-type-punning-well-defined%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      5














      pointer->res.a is fine but the behaviour of pointer->res.b is undefined.



      There could be an arbitrary amount of padding between the a and b members.



      Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.






      share|improve this answer
























      • Thank you! If I ensure that there will be no padding is it then well defined?

        – KBlr
        3 hours ago











      • @KBlr: Yep! Just not portable

        – AndyG
        3 hours ago






      • 2





        pointer->res.a accesses an object (arr1) through an lvalue (pointer->res) in violation of C 2018 6.5 7.

        – Eric Postpischil
        1 hour ago













      • @EricPostpischil one could say that the arr1[0] (because arr1 is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a, which does not violate 6.5.7, because the type of the lvalue is int and the accessed object's type is int.

        – Language Lawyer
        1 hour ago
















      5














      pointer->res.a is fine but the behaviour of pointer->res.b is undefined.



      There could be an arbitrary amount of padding between the a and b members.



      Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.






      share|improve this answer
























      • Thank you! If I ensure that there will be no padding is it then well defined?

        – KBlr
        3 hours ago











      • @KBlr: Yep! Just not portable

        – AndyG
        3 hours ago






      • 2





        pointer->res.a accesses an object (arr1) through an lvalue (pointer->res) in violation of C 2018 6.5 7.

        – Eric Postpischil
        1 hour ago













      • @EricPostpischil one could say that the arr1[0] (because arr1 is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a, which does not violate 6.5.7, because the type of the lvalue is int and the accessed object's type is int.

        – Language Lawyer
        1 hour ago














      5












      5








      5







      pointer->res.a is fine but the behaviour of pointer->res.b is undefined.



      There could be an arbitrary amount of padding between the a and b members.



      Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.






      share|improve this answer













      pointer->res.a is fine but the behaviour of pointer->res.b is undefined.



      There could be an arbitrary amount of padding between the a and b members.



      Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 3 hours ago









      BathshebaBathsheba

      176k27251373




      176k27251373













      • Thank you! If I ensure that there will be no padding is it then well defined?

        – KBlr
        3 hours ago











      • @KBlr: Yep! Just not portable

        – AndyG
        3 hours ago






      • 2





        pointer->res.a accesses an object (arr1) through an lvalue (pointer->res) in violation of C 2018 6.5 7.

        – Eric Postpischil
        1 hour ago













      • @EricPostpischil one could say that the arr1[0] (because arr1 is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a, which does not violate 6.5.7, because the type of the lvalue is int and the accessed object's type is int.

        – Language Lawyer
        1 hour ago



















      • Thank you! If I ensure that there will be no padding is it then well defined?

        – KBlr
        3 hours ago











      • @KBlr: Yep! Just not portable

        – AndyG
        3 hours ago






      • 2





        pointer->res.a accesses an object (arr1) through an lvalue (pointer->res) in violation of C 2018 6.5 7.

        – Eric Postpischil
        1 hour ago













      • @EricPostpischil one could say that the arr1[0] (because arr1 is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a, which does not violate 6.5.7, because the type of the lvalue is int and the accessed object's type is int.

        – Language Lawyer
        1 hour ago

















      Thank you! If I ensure that there will be no padding is it then well defined?

      – KBlr
      3 hours ago





      Thank you! If I ensure that there will be no padding is it then well defined?

      – KBlr
      3 hours ago













      @KBlr: Yep! Just not portable

      – AndyG
      3 hours ago





      @KBlr: Yep! Just not portable

      – AndyG
      3 hours ago




      2




      2





      pointer->res.a accesses an object (arr1) through an lvalue (pointer->res) in violation of C 2018 6.5 7.

      – Eric Postpischil
      1 hour ago







      pointer->res.a accesses an object (arr1) through an lvalue (pointer->res) in violation of C 2018 6.5 7.

      – Eric Postpischil
      1 hour ago















      @EricPostpischil one could say that the arr1[0] (because arr1 is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a, which does not violate 6.5.7, because the type of the lvalue is int and the accessed object's type is int.

      – Language Lawyer
      1 hour ago





      @EricPostpischil one could say that the arr1[0] (because arr1 is converted to a pointer to its first member before the cast) is accessed through an lvalue pointer->res.a, which does not violate 6.5.7, because the type of the lvalue is int and the accessed object's type is int.

      – Language Lawyer
      1 hour ago













      2














      C imposes no rule about how much padding is left between 2 consecutive members of a structure.



      This is why the implementations define many #pragma directives -- specially to change this behaviour.



      So, as the answer of Bathsheba says, ...->b is undefined.



      I answered the very same question some time ago, here.






      share|improve this answer






























        2














        C imposes no rule about how much padding is left between 2 consecutive members of a structure.



        This is why the implementations define many #pragma directives -- specially to change this behaviour.



        So, as the answer of Bathsheba says, ...->b is undefined.



        I answered the very same question some time ago, here.






        share|improve this answer




























          2












          2








          2







          C imposes no rule about how much padding is left between 2 consecutive members of a structure.



          This is why the implementations define many #pragma directives -- specially to change this behaviour.



          So, as the answer of Bathsheba says, ...->b is undefined.



          I answered the very same question some time ago, here.






          share|improve this answer















          C imposes no rule about how much padding is left between 2 consecutive members of a structure.



          This is why the implementations define many #pragma directives -- specially to change this behaviour.



          So, as the answer of Bathsheba says, ...->b is undefined.



          I answered the very same question some time ago, here.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 hours ago

























          answered 3 hours ago









          alinsoaralinsoar

          8,12613047




          8,12613047























              1















              Is this type punning well defined?




              struct result{
              int a,b,c,d;
              }

              union convert {
              int arr[4];
              struct result res;
              }

              int arr1[4] = {1,2,3,5};
              union convert *pointer = (union convert *) arr1;


              (union convert *) arr1 risks alignment failure.




              A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8




              There is no requirement that union convert and int share the same alignment. union convert requirements may exceed int for example.



              Consider this possibility: arr1 lives on int street where all addresses are multiple of 4. union and struct friends lives on "multiple of 8" street. arr1 might have address 0x1004 (not a multiple of 8).



              This type punning is not well defined.






              share|improve this answer


























              • What if I add __attribute__((packed)) to structure ?

                – kiran Biradar
                21 secs ago
















              1















              Is this type punning well defined?




              struct result{
              int a,b,c,d;
              }

              union convert {
              int arr[4];
              struct result res;
              }

              int arr1[4] = {1,2,3,5};
              union convert *pointer = (union convert *) arr1;


              (union convert *) arr1 risks alignment failure.




              A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8




              There is no requirement that union convert and int share the same alignment. union convert requirements may exceed int for example.



              Consider this possibility: arr1 lives on int street where all addresses are multiple of 4. union and struct friends lives on "multiple of 8" street. arr1 might have address 0x1004 (not a multiple of 8).



              This type punning is not well defined.






              share|improve this answer


























              • What if I add __attribute__((packed)) to structure ?

                – kiran Biradar
                21 secs ago














              1












              1








              1








              Is this type punning well defined?




              struct result{
              int a,b,c,d;
              }

              union convert {
              int arr[4];
              struct result res;
              }

              int arr1[4] = {1,2,3,5};
              union convert *pointer = (union convert *) arr1;


              (union convert *) arr1 risks alignment failure.




              A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8




              There is no requirement that union convert and int share the same alignment. union convert requirements may exceed int for example.



              Consider this possibility: arr1 lives on int street where all addresses are multiple of 4. union and struct friends lives on "multiple of 8" street. arr1 might have address 0x1004 (not a multiple of 8).



              This type punning is not well defined.






              share|improve this answer
















              Is this type punning well defined?




              struct result{
              int a,b,c,d;
              }

              union convert {
              int arr[4];
              struct result res;
              }

              int arr1[4] = {1,2,3,5};
              union convert *pointer = (union convert *) arr1;


              (union convert *) arr1 risks alignment failure.




              A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8




              There is no requirement that union convert and int share the same alignment. union convert requirements may exceed int for example.



              Consider this possibility: arr1 lives on int street where all addresses are multiple of 4. union and struct friends lives on "multiple of 8" street. arr1 might have address 0x1004 (not a multiple of 8).



              This type punning is not well defined.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 48 mins ago

























              answered 58 mins ago









              chuxchux

              81.6k871148




              81.6k871148













              • What if I add __attribute__((packed)) to structure ?

                – kiran Biradar
                21 secs ago



















              • What if I add __attribute__((packed)) to structure ?

                – kiran Biradar
                21 secs ago

















              What if I add __attribute__((packed)) to structure ?

              – kiran Biradar
              21 secs ago





              What if I add __attribute__((packed)) to structure ?

              – kiran Biradar
              21 secs ago











              0














              Pointer punning is not safe. Use real union punning instead.



              Assumptions: the struct is properly packed (no padding between the members)



              #include <stdio.h>
              #include <string.h>



              struct __attribute__((packed)) result{
              int a;
              int b;
              int c;
              int d;
              };

              union convert{
              int arr[4];
              struct result res;
              };

              volatile int arr1[4];

              void foo(void)
              {

              union convert cnv;

              memcpy(&cnv, (void *)arr1, sizeof(arr1));

              printf("%d %dn", cnv.res.a, cnv.res.b);
              }


              all modern compilers will optimize out the memcpy call



              https://godbolt.org/z/4qtRIF



              .LC0:
              .string "%d %dn"
              foo:
              mov rsi, QWORD PTR arr1[rip]
              xor eax, eax
              mov rdi, QWORD PTR arr1[rip+8]
              mov edi, OFFSET FLAT:.LC0
              mov rdx, rsi
              sar rdx, 32
              jmp printf





              share|improve this answer
























              • Agree. Deleted.

                – Language Lawyer
                18 mins ago
















              0














              Pointer punning is not safe. Use real union punning instead.



              Assumptions: the struct is properly packed (no padding between the members)



              #include <stdio.h>
              #include <string.h>



              struct __attribute__((packed)) result{
              int a;
              int b;
              int c;
              int d;
              };

              union convert{
              int arr[4];
              struct result res;
              };

              volatile int arr1[4];

              void foo(void)
              {

              union convert cnv;

              memcpy(&cnv, (void *)arr1, sizeof(arr1));

              printf("%d %dn", cnv.res.a, cnv.res.b);
              }


              all modern compilers will optimize out the memcpy call



              https://godbolt.org/z/4qtRIF



              .LC0:
              .string "%d %dn"
              foo:
              mov rsi, QWORD PTR arr1[rip]
              xor eax, eax
              mov rdi, QWORD PTR arr1[rip+8]
              mov edi, OFFSET FLAT:.LC0
              mov rdx, rsi
              sar rdx, 32
              jmp printf





              share|improve this answer
























              • Agree. Deleted.

                – Language Lawyer
                18 mins ago














              0












              0








              0







              Pointer punning is not safe. Use real union punning instead.



              Assumptions: the struct is properly packed (no padding between the members)



              #include <stdio.h>
              #include <string.h>



              struct __attribute__((packed)) result{
              int a;
              int b;
              int c;
              int d;
              };

              union convert{
              int arr[4];
              struct result res;
              };

              volatile int arr1[4];

              void foo(void)
              {

              union convert cnv;

              memcpy(&cnv, (void *)arr1, sizeof(arr1));

              printf("%d %dn", cnv.res.a, cnv.res.b);
              }


              all modern compilers will optimize out the memcpy call



              https://godbolt.org/z/4qtRIF



              .LC0:
              .string "%d %dn"
              foo:
              mov rsi, QWORD PTR arr1[rip]
              xor eax, eax
              mov rdi, QWORD PTR arr1[rip+8]
              mov edi, OFFSET FLAT:.LC0
              mov rdx, rsi
              sar rdx, 32
              jmp printf





              share|improve this answer













              Pointer punning is not safe. Use real union punning instead.



              Assumptions: the struct is properly packed (no padding between the members)



              #include <stdio.h>
              #include <string.h>



              struct __attribute__((packed)) result{
              int a;
              int b;
              int c;
              int d;
              };

              union convert{
              int arr[4];
              struct result res;
              };

              volatile int arr1[4];

              void foo(void)
              {

              union convert cnv;

              memcpy(&cnv, (void *)arr1, sizeof(arr1));

              printf("%d %dn", cnv.res.a, cnv.res.b);
              }


              all modern compilers will optimize out the memcpy call



              https://godbolt.org/z/4qtRIF



              .LC0:
              .string "%d %dn"
              foo:
              mov rsi, QWORD PTR arr1[rip]
              xor eax, eax
              mov rdi, QWORD PTR arr1[rip+8]
              mov edi, OFFSET FLAT:.LC0
              mov rdx, rsi
              sar rdx, 32
              jmp printf






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 3 hours ago









              P__J__P__J__

              9,4912723




              9,4912723













              • Agree. Deleted.

                – Language Lawyer
                18 mins ago



















              • Agree. Deleted.

                – Language Lawyer
                18 mins ago

















              Agree. Deleted.

              – Language Lawyer
              18 mins ago





              Agree. Deleted.

              – Language Lawyer
              18 mins ago











              0














              After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator -> semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):




              A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.




              means that a postfix expression followed by the -> operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert.






              share|improve this answer






























                0














                After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator -> semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):




                A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.




                means that a postfix expression followed by the -> operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert.






                share|improve this answer




























                  0












                  0








                  0







                  After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator -> semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):




                  A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.




                  means that a postfix expression followed by the -> operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert.






                  share|improve this answer















                  After the C++ Standard wording, the C Standard wording looks a bit wobbly to me. But I think that the description of the operator -> semantics (http://port70.net/~nsz/c/c11/n1570.html#6.5.2.3p4) (emphasis is mine):




                  A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.




                  means that a postfix expression followed by the -> operator shall refer to an existing object of the type it points to (there is no such "shall" in the wording, though). And in your case, there is no object of type union convert.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 1 hour ago

























                  answered 1 hour ago









                  Language LawyerLanguage Lawyer

                  115111




                  115111






























                      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%2f54237976%2fis-this-type-punning-well-defined%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

                      Polycentropodidae

                      Magento 2 Error message: Invalid state change requested

                      Paulmy