Dereferenced union member bytes are not the same












1















From the tutorial at learnc, I am experimenting with some really basic stuff on pointers and unions. In the code below I create a struct operator with an anonymous union consisting of a float, double, and int. Since double is the biggest one at eight bytes, I expect to see my int have eight bytes, which it does. However, they are not the same bytes as the double!



typedef enum {
INTEGER = 0,
FLOAT = 1,
DOUBLE = 2,
} operator_type;

typedef struct operator {
operator_type type;

union {
int intNum;
double doubleNum;
float floatNum;
};
} operator_t;

int main() {

operator_t op;
op.type = FLOAT;
op.floatNum = 3.14f;

printf("op.intNum = %inop.doubleNum = %fnop.floatNum = %fn", op.intNum, op.doubleNum, op.floatNum);

printf("op.intNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.intNum) + 0,
&(op.intNum) + 1,
&(op.intNum) + 2,
&(op.intNum) + 3,
&(op.intNum) + 4,
&(op.intNum) + 5,
&(op.intNum) + 6,
&(op.intNum) + 7,
&(op.intNum) + 8
);

printf("op.doubleNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.doubleNum) + 0,
&(op.doubleNum) + 1,
&(op.doubleNum) + 2,
&(op.doubleNum) + 3,
&(op.doubleNum) + 4,
&(op.doubleNum) + 5,
&(op.doubleNum) + 6,
&(op.doubleNum) + 7,
&(op.doubleNum) + 8
);

return 0;
}


I get the output:



op.intNum [-13304, -13300, -13296, -13292, -13288, -13284, -13280, -13276, -13272]
op.doubleNum [-13304, -13296, -13288, -13280, -13272, -13264, -13256, -13248, -13240]


Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum) ?










share|improve this question

























  • What are you printing?

    – gsamaras
    Nov 24 '18 at 21:02











  • The int representation of each of the eight bytes stored by that union?

    – tacos_tacos_tacos
    Nov 24 '18 at 21:04











  • Are you trying to print the addresses or the values of those bytes?

    – Bob__
    Nov 24 '18 at 21:06













  • Sorry, yes the address not the values.

    – tacos_tacos_tacos
    Nov 24 '18 at 21:07











  • To print a pointer you should use the format specifier "%p" and cast to (void *), but those are going to be pointers to int, so you are not going to have the expected result either.

    – Bob__
    Nov 24 '18 at 21:08


















1















From the tutorial at learnc, I am experimenting with some really basic stuff on pointers and unions. In the code below I create a struct operator with an anonymous union consisting of a float, double, and int. Since double is the biggest one at eight bytes, I expect to see my int have eight bytes, which it does. However, they are not the same bytes as the double!



typedef enum {
INTEGER = 0,
FLOAT = 1,
DOUBLE = 2,
} operator_type;

typedef struct operator {
operator_type type;

union {
int intNum;
double doubleNum;
float floatNum;
};
} operator_t;

int main() {

operator_t op;
op.type = FLOAT;
op.floatNum = 3.14f;

printf("op.intNum = %inop.doubleNum = %fnop.floatNum = %fn", op.intNum, op.doubleNum, op.floatNum);

printf("op.intNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.intNum) + 0,
&(op.intNum) + 1,
&(op.intNum) + 2,
&(op.intNum) + 3,
&(op.intNum) + 4,
&(op.intNum) + 5,
&(op.intNum) + 6,
&(op.intNum) + 7,
&(op.intNum) + 8
);

printf("op.doubleNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.doubleNum) + 0,
&(op.doubleNum) + 1,
&(op.doubleNum) + 2,
&(op.doubleNum) + 3,
&(op.doubleNum) + 4,
&(op.doubleNum) + 5,
&(op.doubleNum) + 6,
&(op.doubleNum) + 7,
&(op.doubleNum) + 8
);

return 0;
}


I get the output:



op.intNum [-13304, -13300, -13296, -13292, -13288, -13284, -13280, -13276, -13272]
op.doubleNum [-13304, -13296, -13288, -13280, -13272, -13264, -13256, -13248, -13240]


Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum) ?










share|improve this question

























  • What are you printing?

    – gsamaras
    Nov 24 '18 at 21:02











  • The int representation of each of the eight bytes stored by that union?

    – tacos_tacos_tacos
    Nov 24 '18 at 21:04











  • Are you trying to print the addresses or the values of those bytes?

    – Bob__
    Nov 24 '18 at 21:06













  • Sorry, yes the address not the values.

    – tacos_tacos_tacos
    Nov 24 '18 at 21:07











  • To print a pointer you should use the format specifier "%p" and cast to (void *), but those are going to be pointers to int, so you are not going to have the expected result either.

    – Bob__
    Nov 24 '18 at 21:08
















1












1








1








From the tutorial at learnc, I am experimenting with some really basic stuff on pointers and unions. In the code below I create a struct operator with an anonymous union consisting of a float, double, and int. Since double is the biggest one at eight bytes, I expect to see my int have eight bytes, which it does. However, they are not the same bytes as the double!



typedef enum {
INTEGER = 0,
FLOAT = 1,
DOUBLE = 2,
} operator_type;

typedef struct operator {
operator_type type;

union {
int intNum;
double doubleNum;
float floatNum;
};
} operator_t;

int main() {

operator_t op;
op.type = FLOAT;
op.floatNum = 3.14f;

printf("op.intNum = %inop.doubleNum = %fnop.floatNum = %fn", op.intNum, op.doubleNum, op.floatNum);

printf("op.intNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.intNum) + 0,
&(op.intNum) + 1,
&(op.intNum) + 2,
&(op.intNum) + 3,
&(op.intNum) + 4,
&(op.intNum) + 5,
&(op.intNum) + 6,
&(op.intNum) + 7,
&(op.intNum) + 8
);

printf("op.doubleNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.doubleNum) + 0,
&(op.doubleNum) + 1,
&(op.doubleNum) + 2,
&(op.doubleNum) + 3,
&(op.doubleNum) + 4,
&(op.doubleNum) + 5,
&(op.doubleNum) + 6,
&(op.doubleNum) + 7,
&(op.doubleNum) + 8
);

return 0;
}


I get the output:



op.intNum [-13304, -13300, -13296, -13292, -13288, -13284, -13280, -13276, -13272]
op.doubleNum [-13304, -13296, -13288, -13280, -13272, -13264, -13256, -13248, -13240]


Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum) ?










share|improve this question
















From the tutorial at learnc, I am experimenting with some really basic stuff on pointers and unions. In the code below I create a struct operator with an anonymous union consisting of a float, double, and int. Since double is the biggest one at eight bytes, I expect to see my int have eight bytes, which it does. However, they are not the same bytes as the double!



typedef enum {
INTEGER = 0,
FLOAT = 1,
DOUBLE = 2,
} operator_type;

typedef struct operator {
operator_type type;

union {
int intNum;
double doubleNum;
float floatNum;
};
} operator_t;

int main() {

operator_t op;
op.type = FLOAT;
op.floatNum = 3.14f;

printf("op.intNum = %inop.doubleNum = %fnop.floatNum = %fn", op.intNum, op.doubleNum, op.floatNum);

printf("op.intNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.intNum) + 0,
&(op.intNum) + 1,
&(op.intNum) + 2,
&(op.intNum) + 3,
&(op.intNum) + 4,
&(op.intNum) + 5,
&(op.intNum) + 6,
&(op.intNum) + 7,
&(op.intNum) + 8
);

printf("op.doubleNum [%i, %i, %i, %i, %i, %i, %i, %i, %i]",
&(op.doubleNum) + 0,
&(op.doubleNum) + 1,
&(op.doubleNum) + 2,
&(op.doubleNum) + 3,
&(op.doubleNum) + 4,
&(op.doubleNum) + 5,
&(op.doubleNum) + 6,
&(op.doubleNum) + 7,
&(op.doubleNum) + 8
);

return 0;
}


I get the output:



op.intNum [-13304, -13300, -13296, -13292, -13288, -13284, -13280, -13276, -13272]
op.doubleNum [-13304, -13296, -13288, -13280, -13272, -13264, -13256, -13248, -13240]


Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum) ?







c memory unions






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 21:16









gsamaras

51.1k2399186




51.1k2399186










asked Nov 24 '18 at 20:59









tacos_tacos_tacostacos_tacos_tacos

5,886855107




5,886855107













  • What are you printing?

    – gsamaras
    Nov 24 '18 at 21:02











  • The int representation of each of the eight bytes stored by that union?

    – tacos_tacos_tacos
    Nov 24 '18 at 21:04











  • Are you trying to print the addresses or the values of those bytes?

    – Bob__
    Nov 24 '18 at 21:06













  • Sorry, yes the address not the values.

    – tacos_tacos_tacos
    Nov 24 '18 at 21:07











  • To print a pointer you should use the format specifier "%p" and cast to (void *), but those are going to be pointers to int, so you are not going to have the expected result either.

    – Bob__
    Nov 24 '18 at 21:08





















  • What are you printing?

    – gsamaras
    Nov 24 '18 at 21:02











  • The int representation of each of the eight bytes stored by that union?

    – tacos_tacos_tacos
    Nov 24 '18 at 21:04











  • Are you trying to print the addresses or the values of those bytes?

    – Bob__
    Nov 24 '18 at 21:06













  • Sorry, yes the address not the values.

    – tacos_tacos_tacos
    Nov 24 '18 at 21:07











  • To print a pointer you should use the format specifier "%p" and cast to (void *), but those are going to be pointers to int, so you are not going to have the expected result either.

    – Bob__
    Nov 24 '18 at 21:08



















What are you printing?

– gsamaras
Nov 24 '18 at 21:02





What are you printing?

– gsamaras
Nov 24 '18 at 21:02













The int representation of each of the eight bytes stored by that union?

– tacos_tacos_tacos
Nov 24 '18 at 21:04





The int representation of each of the eight bytes stored by that union?

– tacos_tacos_tacos
Nov 24 '18 at 21:04













Are you trying to print the addresses or the values of those bytes?

– Bob__
Nov 24 '18 at 21:06







Are you trying to print the addresses or the values of those bytes?

– Bob__
Nov 24 '18 at 21:06















Sorry, yes the address not the values.

– tacos_tacos_tacos
Nov 24 '18 at 21:07





Sorry, yes the address not the values.

– tacos_tacos_tacos
Nov 24 '18 at 21:07













To print a pointer you should use the format specifier "%p" and cast to (void *), but those are going to be pointers to int, so you are not going to have the expected result either.

– Bob__
Nov 24 '18 at 21:08







To print a pointer you should use the format specifier "%p" and cast to (void *), but those are going to be pointers to int, so you are not going to have the expected result either.

– Bob__
Nov 24 '18 at 21:08














3 Answers
3






active

oldest

votes


















1















Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum)?




Yes, they should, and they are.



In order to print an address, use %p as the format specifier, and cast it to void*. Read more in How to print variable addresses in C?



Edit: Why do I have to cast my memory address to (void *)?






share|improve this answer


























  • So one more quick question ... actually, casting them to (void *) is what made them have the same output, the output format might have been nonsense because of the %i, but it is interesting to me still that the (void *) cast is necessary.

    – tacos_tacos_tacos
    Nov 24 '18 at 21:21











  • @tacos_tacos_tacos About that, see e.g. stackoverflow.com/questions/24867814/…

    – Bob__
    Nov 24 '18 at 21:24






  • 1





    @tacos_tacos_tacos I posted a duplicated of Bob. Pointers can have different representations, so they need to be casted into something generic..

    – gsamaras
    Nov 24 '18 at 21:26



















1














&(op.intNum) + 1 is the address immediately after the end of op.intNum.



That is, if op.intNum is at address A, and sizeof op.intNum is 4, then the expression you wrote has value A+4.



That's a consequence of how pointer arithmetic is defined.






share|improve this answer

































    0














    In your case you don't dereference union, for dereferencing you need to declare op as pointer.



    FYI:



    In your code you print




    • address of int member, and sizeof(int) is 4 in your architecture, so increment by 1 , your address will be address + sizeof(int)


    • address of double member and sizeof(double) in 8, in this case each after each increment your address will be address + 8



    Hope this will help.






    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%2f53462317%2fdereferenced-union-member-bytes-are-not-the-same%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









      1















      Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum)?




      Yes, they should, and they are.



      In order to print an address, use %p as the format specifier, and cast it to void*. Read more in How to print variable addresses in C?



      Edit: Why do I have to cast my memory address to (void *)?






      share|improve this answer


























      • So one more quick question ... actually, casting them to (void *) is what made them have the same output, the output format might have been nonsense because of the %i, but it is interesting to me still that the (void *) cast is necessary.

        – tacos_tacos_tacos
        Nov 24 '18 at 21:21











      • @tacos_tacos_tacos About that, see e.g. stackoverflow.com/questions/24867814/…

        – Bob__
        Nov 24 '18 at 21:24






      • 1





        @tacos_tacos_tacos I posted a duplicated of Bob. Pointers can have different representations, so they need to be casted into something generic..

        – gsamaras
        Nov 24 '18 at 21:26
















      1















      Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum)?




      Yes, they should, and they are.



      In order to print an address, use %p as the format specifier, and cast it to void*. Read more in How to print variable addresses in C?



      Edit: Why do I have to cast my memory address to (void *)?






      share|improve this answer


























      • So one more quick question ... actually, casting them to (void *) is what made them have the same output, the output format might have been nonsense because of the %i, but it is interesting to me still that the (void *) cast is necessary.

        – tacos_tacos_tacos
        Nov 24 '18 at 21:21











      • @tacos_tacos_tacos About that, see e.g. stackoverflow.com/questions/24867814/…

        – Bob__
        Nov 24 '18 at 21:24






      • 1





        @tacos_tacos_tacos I posted a duplicated of Bob. Pointers can have different representations, so they need to be casted into something generic..

        – gsamaras
        Nov 24 '18 at 21:26














      1












      1








      1








      Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum)?




      Yes, they should, and they are.



      In order to print an address, use %p as the format specifier, and cast it to void*. Read more in How to print variable addresses in C?



      Edit: Why do I have to cast my memory address to (void *)?






      share|improve this answer
















      Shouldn't &(op.intNum) == &(op.doubleNum) == &(op.floatNum)?




      Yes, they should, and they are.



      In order to print an address, use %p as the format specifier, and cast it to void*. Read more in How to print variable addresses in C?



      Edit: Why do I have to cast my memory address to (void *)?







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 24 '18 at 21:25

























      answered Nov 24 '18 at 21:16









      gsamarasgsamaras

      51.1k2399186




      51.1k2399186













      • So one more quick question ... actually, casting them to (void *) is what made them have the same output, the output format might have been nonsense because of the %i, but it is interesting to me still that the (void *) cast is necessary.

        – tacos_tacos_tacos
        Nov 24 '18 at 21:21











      • @tacos_tacos_tacos About that, see e.g. stackoverflow.com/questions/24867814/…

        – Bob__
        Nov 24 '18 at 21:24






      • 1





        @tacos_tacos_tacos I posted a duplicated of Bob. Pointers can have different representations, so they need to be casted into something generic..

        – gsamaras
        Nov 24 '18 at 21:26



















      • So one more quick question ... actually, casting them to (void *) is what made them have the same output, the output format might have been nonsense because of the %i, but it is interesting to me still that the (void *) cast is necessary.

        – tacos_tacos_tacos
        Nov 24 '18 at 21:21











      • @tacos_tacos_tacos About that, see e.g. stackoverflow.com/questions/24867814/…

        – Bob__
        Nov 24 '18 at 21:24






      • 1





        @tacos_tacos_tacos I posted a duplicated of Bob. Pointers can have different representations, so they need to be casted into something generic..

        – gsamaras
        Nov 24 '18 at 21:26

















      So one more quick question ... actually, casting them to (void *) is what made them have the same output, the output format might have been nonsense because of the %i, but it is interesting to me still that the (void *) cast is necessary.

      – tacos_tacos_tacos
      Nov 24 '18 at 21:21





      So one more quick question ... actually, casting them to (void *) is what made them have the same output, the output format might have been nonsense because of the %i, but it is interesting to me still that the (void *) cast is necessary.

      – tacos_tacos_tacos
      Nov 24 '18 at 21:21













      @tacos_tacos_tacos About that, see e.g. stackoverflow.com/questions/24867814/…

      – Bob__
      Nov 24 '18 at 21:24





      @tacos_tacos_tacos About that, see e.g. stackoverflow.com/questions/24867814/…

      – Bob__
      Nov 24 '18 at 21:24




      1




      1





      @tacos_tacos_tacos I posted a duplicated of Bob. Pointers can have different representations, so they need to be casted into something generic..

      – gsamaras
      Nov 24 '18 at 21:26





      @tacos_tacos_tacos I posted a duplicated of Bob. Pointers can have different representations, so they need to be casted into something generic..

      – gsamaras
      Nov 24 '18 at 21:26













      1














      &(op.intNum) + 1 is the address immediately after the end of op.intNum.



      That is, if op.intNum is at address A, and sizeof op.intNum is 4, then the expression you wrote has value A+4.



      That's a consequence of how pointer arithmetic is defined.






      share|improve this answer






























        1














        &(op.intNum) + 1 is the address immediately after the end of op.intNum.



        That is, if op.intNum is at address A, and sizeof op.intNum is 4, then the expression you wrote has value A+4.



        That's a consequence of how pointer arithmetic is defined.






        share|improve this answer




























          1












          1








          1







          &(op.intNum) + 1 is the address immediately after the end of op.intNum.



          That is, if op.intNum is at address A, and sizeof op.intNum is 4, then the expression you wrote has value A+4.



          That's a consequence of how pointer arithmetic is defined.






          share|improve this answer















          &(op.intNum) + 1 is the address immediately after the end of op.intNum.



          That is, if op.intNum is at address A, and sizeof op.intNum is 4, then the expression you wrote has value A+4.



          That's a consequence of how pointer arithmetic is defined.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 24 '18 at 21:27









          gsamaras

          51.1k2399186




          51.1k2399186










          answered Nov 24 '18 at 21:19









          davedave

          111




          111























              0














              In your case you don't dereference union, for dereferencing you need to declare op as pointer.



              FYI:



              In your code you print




              • address of int member, and sizeof(int) is 4 in your architecture, so increment by 1 , your address will be address + sizeof(int)


              • address of double member and sizeof(double) in 8, in this case each after each increment your address will be address + 8



              Hope this will help.






              share|improve this answer




























                0














                In your case you don't dereference union, for dereferencing you need to declare op as pointer.



                FYI:



                In your code you print




                • address of int member, and sizeof(int) is 4 in your architecture, so increment by 1 , your address will be address + sizeof(int)


                • address of double member and sizeof(double) in 8, in this case each after each increment your address will be address + 8



                Hope this will help.






                share|improve this answer


























                  0












                  0








                  0







                  In your case you don't dereference union, for dereferencing you need to declare op as pointer.



                  FYI:



                  In your code you print




                  • address of int member, and sizeof(int) is 4 in your architecture, so increment by 1 , your address will be address + sizeof(int)


                  • address of double member and sizeof(double) in 8, in this case each after each increment your address will be address + 8



                  Hope this will help.






                  share|improve this answer













                  In your case you don't dereference union, for dereferencing you need to declare op as pointer.



                  FYI:



                  In your code you print




                  • address of int member, and sizeof(int) is 4 in your architecture, so increment by 1 , your address will be address + sizeof(int)


                  • address of double member and sizeof(double) in 8, in this case each after each increment your address will be address + 8



                  Hope this will help.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 24 '18 at 21:29









                  SG92SG92

                  416




                  416






























                      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%2f53462317%2fdereferenced-union-member-bytes-are-not-the-same%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)