Why are the outputs of printf and std::cout different












28















I tried the following code of C++. However, the outputs of printf and std::cout are different. Can someone tell me why?



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

int main()
{
printf("%dn", &Foo::c); //the output is 8
std::cout << &Foo::c <<"n"; //the output is 1
}









share|improve this question









New contributor




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
















  • 14





    main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]

    – YesThatIsMyName
    11 hours ago






  • 6





    @YesThatIsMyName -- the value of c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.

    – Pete Becker
    9 hours ago
















28















I tried the following code of C++. However, the outputs of printf and std::cout are different. Can someone tell me why?



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

int main()
{
printf("%dn", &Foo::c); //the output is 8
std::cout << &Foo::c <<"n"; //the output is 1
}









share|improve this question









New contributor




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
















  • 14





    main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]

    – YesThatIsMyName
    11 hours ago






  • 6





    @YesThatIsMyName -- the value of c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.

    – Pete Becker
    9 hours ago














28












28








28


1






I tried the following code of C++. However, the outputs of printf and std::cout are different. Can someone tell me why?



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

int main()
{
printf("%dn", &Foo::c); //the output is 8
std::cout << &Foo::c <<"n"; //the output is 1
}









share|improve this question









New contributor




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












I tried the following code of C++. However, the outputs of printf and std::cout are different. Can someone tell me why?



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

int main()
{
printf("%dn", &Foo::c); //the output is 8
std::cout << &Foo::c <<"n"; //the output is 1
}






c++






share|improve this question









New contributor




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











share|improve this question









New contributor




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









share|improve this question




share|improve this question








edited 11 hours ago









kvantour

9,35931531




9,35931531






New contributor




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









asked 11 hours ago









uu dduu dd

14915




14915




New contributor




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





New contributor





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






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








  • 14





    main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]

    – YesThatIsMyName
    11 hours ago






  • 6





    @YesThatIsMyName -- the value of c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.

    – Pete Becker
    9 hours ago














  • 14





    main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]

    – YesThatIsMyName
    11 hours ago






  • 6





    @YesThatIsMyName -- the value of c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.

    – Pete Becker
    9 hours ago








14




14





main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]

– YesThatIsMyName
11 hours ago





main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]

– YesThatIsMyName
11 hours ago




6




6





@YesThatIsMyName -- the value of c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.

– Pete Becker
9 hours ago





@YesThatIsMyName -- the value of c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.

– Pete Becker
9 hours ago












3 Answers
3






active

oldest

votes


















50














printf("%dn", &Foo::c): this is undefined behavior, as &Foo::c is not an integer, but a pointer to member (but, actually, it is usual that the compiler stores pointer to data member as offset, and as 8 is the offset of Foo::c, 8 is printed).



std::cout << &Foo::c: this prints the value &Foo::c. As iostream doesn't have a pointer to member printer, it chooses the closest one: it converts it to bool, and prints it as integer. As &Foo::c converted to bool is true, 1 is printed.






share|improve this answer


























  • You know member-pointers have to take into account the possibility of virtual inheritance?

    – Deduplicator
    10 hours ago








  • 1





    @Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent of void*, each class has its own unique types of member pointers. Even sizeof(int Foo::*) may depend on Foo.

    – MSalters
    10 hours ago











  • @MSalters No. You can have and use a int Foo::* perfectly fine while Foo is still incomplete and in no danger of being completed anytime soon. Admittedly, MS especially likes to play fast and loose with member-pointers of any kind.

    – Deduplicator
    10 hours ago








  • 4





    @all - I held my peace until now, but can we stop with the "member-pointer" business? The term is "pointer-to-member". And when it comes to technical terms, it matters. Just as "chocolate milk" isn't the same as "milk chocolate". </pedantry>

    – StoryTeller
    10 hours ago








  • 1





    @StoryTeller: and yet we have std::is_member_pointer :)

    – geza
    9 hours ago



















13














The output is different because the behavior of your printf is undefined.



A pointer to member (like the one produced from &Foo::c) is not an integer. The printf function expects an integer, since you told it too with the %d specifier.



You can amend it by adding a cast to bool, like this:



printf("%dn", (bool)&Foo::c)


A pointer to member may be converted to a bool (which you do with the cast), and the bool then undergoes integral promotion to an int on account of being an integral variadic argument to a variadic function.



Speaking of the conversion to bool, it's exactly the conversion that is applied implicitly by attempting to call std::ostream's operator<<. Since there isn't an overload of the operator that supports pointers to members, overload resolution selects another that is callable after implicitly converting &Foo::c to a boolean.






share|improve this answer

































    0














    In addition to the more literal answer about why the compiler interpreted your code the way it did: you seem to have an XY problem You’re trying to format a pointer-to-member as an integer, which strongly suggests you meant to do something different.



    If what you wanted was an int value stored in .c, you either need to create an instance Foo some_foo; and take some_foo.c, or else you need to declare Foo::c a static member, so there’s one unambiguous Foo::c across the entire class. Do not take the address in this case.



    If what you wanted was to take an address of the .c member of some Foo, you should do as above so that Foo::c is static and refers to one specific variable, or else declare an instance and take its .c member, then take the address. The correct printf() specifier for an object pointer is %p, and to print an object pointer representation with <iostream>, convert it to void*:



    printf( "%pn", &some_foo.c );
    std::cout << static_cast<void*>{&some_foo.c} << 'n';


    If what you want is the offset of Foo::c within class Foo, you want the offsetof() macro in <stddef.h>. Since its return value is size_t, which is not the same size as int on 64-bit platforms, you would want to either cast the result explicitly or pass printf() the z type specifier:



    #include <stddef.h>

    /* ... */

    constexpr size_t offset_c = offsetof( Foo, c );
    printf( "%zun", offset_c );
    cout << offset_c << 'n';


    Whatever you were trying to do, if your compiler didn’t warn you about the type mismatch, you ought to turn on more warnings. This is especially true for someone coding by trial and error until the program compiles.






    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
      });


      }
      });






      uu dd is a new contributor. Be nice, and check out our Code of Conduct.










      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55161182%2fwhy-are-the-outputs-of-printf-and-stdcout-different%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









      50














      printf("%dn", &Foo::c): this is undefined behavior, as &Foo::c is not an integer, but a pointer to member (but, actually, it is usual that the compiler stores pointer to data member as offset, and as 8 is the offset of Foo::c, 8 is printed).



      std::cout << &Foo::c: this prints the value &Foo::c. As iostream doesn't have a pointer to member printer, it chooses the closest one: it converts it to bool, and prints it as integer. As &Foo::c converted to bool is true, 1 is printed.






      share|improve this answer


























      • You know member-pointers have to take into account the possibility of virtual inheritance?

        – Deduplicator
        10 hours ago








      • 1





        @Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent of void*, each class has its own unique types of member pointers. Even sizeof(int Foo::*) may depend on Foo.

        – MSalters
        10 hours ago











      • @MSalters No. You can have and use a int Foo::* perfectly fine while Foo is still incomplete and in no danger of being completed anytime soon. Admittedly, MS especially likes to play fast and loose with member-pointers of any kind.

        – Deduplicator
        10 hours ago








      • 4





        @all - I held my peace until now, but can we stop with the "member-pointer" business? The term is "pointer-to-member". And when it comes to technical terms, it matters. Just as "chocolate milk" isn't the same as "milk chocolate". </pedantry>

        – StoryTeller
        10 hours ago








      • 1





        @StoryTeller: and yet we have std::is_member_pointer :)

        – geza
        9 hours ago
















      50














      printf("%dn", &Foo::c): this is undefined behavior, as &Foo::c is not an integer, but a pointer to member (but, actually, it is usual that the compiler stores pointer to data member as offset, and as 8 is the offset of Foo::c, 8 is printed).



      std::cout << &Foo::c: this prints the value &Foo::c. As iostream doesn't have a pointer to member printer, it chooses the closest one: it converts it to bool, and prints it as integer. As &Foo::c converted to bool is true, 1 is printed.






      share|improve this answer


























      • You know member-pointers have to take into account the possibility of virtual inheritance?

        – Deduplicator
        10 hours ago








      • 1





        @Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent of void*, each class has its own unique types of member pointers. Even sizeof(int Foo::*) may depend on Foo.

        – MSalters
        10 hours ago











      • @MSalters No. You can have and use a int Foo::* perfectly fine while Foo is still incomplete and in no danger of being completed anytime soon. Admittedly, MS especially likes to play fast and loose with member-pointers of any kind.

        – Deduplicator
        10 hours ago








      • 4





        @all - I held my peace until now, but can we stop with the "member-pointer" business? The term is "pointer-to-member". And when it comes to technical terms, it matters. Just as "chocolate milk" isn't the same as "milk chocolate". </pedantry>

        – StoryTeller
        10 hours ago








      • 1





        @StoryTeller: and yet we have std::is_member_pointer :)

        – geza
        9 hours ago














      50












      50








      50







      printf("%dn", &Foo::c): this is undefined behavior, as &Foo::c is not an integer, but a pointer to member (but, actually, it is usual that the compiler stores pointer to data member as offset, and as 8 is the offset of Foo::c, 8 is printed).



      std::cout << &Foo::c: this prints the value &Foo::c. As iostream doesn't have a pointer to member printer, it chooses the closest one: it converts it to bool, and prints it as integer. As &Foo::c converted to bool is true, 1 is printed.






      share|improve this answer















      printf("%dn", &Foo::c): this is undefined behavior, as &Foo::c is not an integer, but a pointer to member (but, actually, it is usual that the compiler stores pointer to data member as offset, and as 8 is the offset of Foo::c, 8 is printed).



      std::cout << &Foo::c: this prints the value &Foo::c. As iostream doesn't have a pointer to member printer, it chooses the closest one: it converts it to bool, and prints it as integer. As &Foo::c converted to bool is true, 1 is printed.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 9 hours ago

























      answered 11 hours ago









      gezageza

      13.3k33078




      13.3k33078













      • You know member-pointers have to take into account the possibility of virtual inheritance?

        – Deduplicator
        10 hours ago








      • 1





        @Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent of void*, each class has its own unique types of member pointers. Even sizeof(int Foo::*) may depend on Foo.

        – MSalters
        10 hours ago











      • @MSalters No. You can have and use a int Foo::* perfectly fine while Foo is still incomplete and in no danger of being completed anytime soon. Admittedly, MS especially likes to play fast and loose with member-pointers of any kind.

        – Deduplicator
        10 hours ago








      • 4





        @all - I held my peace until now, but can we stop with the "member-pointer" business? The term is "pointer-to-member". And when it comes to technical terms, it matters. Just as "chocolate milk" isn't the same as "milk chocolate". </pedantry>

        – StoryTeller
        10 hours ago








      • 1





        @StoryTeller: and yet we have std::is_member_pointer :)

        – geza
        9 hours ago



















      • You know member-pointers have to take into account the possibility of virtual inheritance?

        – Deduplicator
        10 hours ago








      • 1





        @Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent of void*, each class has its own unique types of member pointers. Even sizeof(int Foo::*) may depend on Foo.

        – MSalters
        10 hours ago











      • @MSalters No. You can have and use a int Foo::* perfectly fine while Foo is still incomplete and in no danger of being completed anytime soon. Admittedly, MS especially likes to play fast and loose with member-pointers of any kind.

        – Deduplicator
        10 hours ago








      • 4





        @all - I held my peace until now, but can we stop with the "member-pointer" business? The term is "pointer-to-member". And when it comes to technical terms, it matters. Just as "chocolate milk" isn't the same as "milk chocolate". </pedantry>

        – StoryTeller
        10 hours ago








      • 1





        @StoryTeller: and yet we have std::is_member_pointer :)

        – geza
        9 hours ago

















      You know member-pointers have to take into account the possibility of virtual inheritance?

      – Deduplicator
      10 hours ago







      You know member-pointers have to take into account the possibility of virtual inheritance?

      – Deduplicator
      10 hours ago






      1




      1





      @Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent of void*, each class has its own unique types of member pointers. Even sizeof(int Foo::*) may depend on Foo.

      – MSalters
      10 hours ago





      @Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent of void*, each class has its own unique types of member pointers. Even sizeof(int Foo::*) may depend on Foo.

      – MSalters
      10 hours ago













      @MSalters No. You can have and use a int Foo::* perfectly fine while Foo is still incomplete and in no danger of being completed anytime soon. Admittedly, MS especially likes to play fast and loose with member-pointers of any kind.

      – Deduplicator
      10 hours ago







      @MSalters No. You can have and use a int Foo::* perfectly fine while Foo is still incomplete and in no danger of being completed anytime soon. Admittedly, MS especially likes to play fast and loose with member-pointers of any kind.

      – Deduplicator
      10 hours ago






      4




      4





      @all - I held my peace until now, but can we stop with the "member-pointer" business? The term is "pointer-to-member". And when it comes to technical terms, it matters. Just as "chocolate milk" isn't the same as "milk chocolate". </pedantry>

      – StoryTeller
      10 hours ago







      @all - I held my peace until now, but can we stop with the "member-pointer" business? The term is "pointer-to-member". And when it comes to technical terms, it matters. Just as "chocolate milk" isn't the same as "milk chocolate". </pedantry>

      – StoryTeller
      10 hours ago






      1




      1





      @StoryTeller: and yet we have std::is_member_pointer :)

      – geza
      9 hours ago





      @StoryTeller: and yet we have std::is_member_pointer :)

      – geza
      9 hours ago













      13














      The output is different because the behavior of your printf is undefined.



      A pointer to member (like the one produced from &Foo::c) is not an integer. The printf function expects an integer, since you told it too with the %d specifier.



      You can amend it by adding a cast to bool, like this:



      printf("%dn", (bool)&Foo::c)


      A pointer to member may be converted to a bool (which you do with the cast), and the bool then undergoes integral promotion to an int on account of being an integral variadic argument to a variadic function.



      Speaking of the conversion to bool, it's exactly the conversion that is applied implicitly by attempting to call std::ostream's operator<<. Since there isn't an overload of the operator that supports pointers to members, overload resolution selects another that is callable after implicitly converting &Foo::c to a boolean.






      share|improve this answer






























        13














        The output is different because the behavior of your printf is undefined.



        A pointer to member (like the one produced from &Foo::c) is not an integer. The printf function expects an integer, since you told it too with the %d specifier.



        You can amend it by adding a cast to bool, like this:



        printf("%dn", (bool)&Foo::c)


        A pointer to member may be converted to a bool (which you do with the cast), and the bool then undergoes integral promotion to an int on account of being an integral variadic argument to a variadic function.



        Speaking of the conversion to bool, it's exactly the conversion that is applied implicitly by attempting to call std::ostream's operator<<. Since there isn't an overload of the operator that supports pointers to members, overload resolution selects another that is callable after implicitly converting &Foo::c to a boolean.






        share|improve this answer




























          13












          13








          13







          The output is different because the behavior of your printf is undefined.



          A pointer to member (like the one produced from &Foo::c) is not an integer. The printf function expects an integer, since you told it too with the %d specifier.



          You can amend it by adding a cast to bool, like this:



          printf("%dn", (bool)&Foo::c)


          A pointer to member may be converted to a bool (which you do with the cast), and the bool then undergoes integral promotion to an int on account of being an integral variadic argument to a variadic function.



          Speaking of the conversion to bool, it's exactly the conversion that is applied implicitly by attempting to call std::ostream's operator<<. Since there isn't an overload of the operator that supports pointers to members, overload resolution selects another that is callable after implicitly converting &Foo::c to a boolean.






          share|improve this answer















          The output is different because the behavior of your printf is undefined.



          A pointer to member (like the one produced from &Foo::c) is not an integer. The printf function expects an integer, since you told it too with the %d specifier.



          You can amend it by adding a cast to bool, like this:



          printf("%dn", (bool)&Foo::c)


          A pointer to member may be converted to a bool (which you do with the cast), and the bool then undergoes integral promotion to an int on account of being an integral variadic argument to a variadic function.



          Speaking of the conversion to bool, it's exactly the conversion that is applied implicitly by attempting to call std::ostream's operator<<. Since there isn't an overload of the operator that supports pointers to members, overload resolution selects another that is callable after implicitly converting &Foo::c to a boolean.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 10 hours ago

























          answered 11 hours ago









          StoryTellerStoryTeller

          102k12214278




          102k12214278























              0














              In addition to the more literal answer about why the compiler interpreted your code the way it did: you seem to have an XY problem You’re trying to format a pointer-to-member as an integer, which strongly suggests you meant to do something different.



              If what you wanted was an int value stored in .c, you either need to create an instance Foo some_foo; and take some_foo.c, or else you need to declare Foo::c a static member, so there’s one unambiguous Foo::c across the entire class. Do not take the address in this case.



              If what you wanted was to take an address of the .c member of some Foo, you should do as above so that Foo::c is static and refers to one specific variable, or else declare an instance and take its .c member, then take the address. The correct printf() specifier for an object pointer is %p, and to print an object pointer representation with <iostream>, convert it to void*:



              printf( "%pn", &some_foo.c );
              std::cout << static_cast<void*>{&some_foo.c} << 'n';


              If what you want is the offset of Foo::c within class Foo, you want the offsetof() macro in <stddef.h>. Since its return value is size_t, which is not the same size as int on 64-bit platforms, you would want to either cast the result explicitly or pass printf() the z type specifier:



              #include <stddef.h>

              /* ... */

              constexpr size_t offset_c = offsetof( Foo, c );
              printf( "%zun", offset_c );
              cout << offset_c << 'n';


              Whatever you were trying to do, if your compiler didn’t warn you about the type mismatch, you ought to turn on more warnings. This is especially true for someone coding by trial and error until the program compiles.






              share|improve this answer




























                0














                In addition to the more literal answer about why the compiler interpreted your code the way it did: you seem to have an XY problem You’re trying to format a pointer-to-member as an integer, which strongly suggests you meant to do something different.



                If what you wanted was an int value stored in .c, you either need to create an instance Foo some_foo; and take some_foo.c, or else you need to declare Foo::c a static member, so there’s one unambiguous Foo::c across the entire class. Do not take the address in this case.



                If what you wanted was to take an address of the .c member of some Foo, you should do as above so that Foo::c is static and refers to one specific variable, or else declare an instance and take its .c member, then take the address. The correct printf() specifier for an object pointer is %p, and to print an object pointer representation with <iostream>, convert it to void*:



                printf( "%pn", &some_foo.c );
                std::cout << static_cast<void*>{&some_foo.c} << 'n';


                If what you want is the offset of Foo::c within class Foo, you want the offsetof() macro in <stddef.h>. Since its return value is size_t, which is not the same size as int on 64-bit platforms, you would want to either cast the result explicitly or pass printf() the z type specifier:



                #include <stddef.h>

                /* ... */

                constexpr size_t offset_c = offsetof( Foo, c );
                printf( "%zun", offset_c );
                cout << offset_c << 'n';


                Whatever you were trying to do, if your compiler didn’t warn you about the type mismatch, you ought to turn on more warnings. This is especially true for someone coding by trial and error until the program compiles.






                share|improve this answer


























                  0












                  0








                  0







                  In addition to the more literal answer about why the compiler interpreted your code the way it did: you seem to have an XY problem You’re trying to format a pointer-to-member as an integer, which strongly suggests you meant to do something different.



                  If what you wanted was an int value stored in .c, you either need to create an instance Foo some_foo; and take some_foo.c, or else you need to declare Foo::c a static member, so there’s one unambiguous Foo::c across the entire class. Do not take the address in this case.



                  If what you wanted was to take an address of the .c member of some Foo, you should do as above so that Foo::c is static and refers to one specific variable, or else declare an instance and take its .c member, then take the address. The correct printf() specifier for an object pointer is %p, and to print an object pointer representation with <iostream>, convert it to void*:



                  printf( "%pn", &some_foo.c );
                  std::cout << static_cast<void*>{&some_foo.c} << 'n';


                  If what you want is the offset of Foo::c within class Foo, you want the offsetof() macro in <stddef.h>. Since its return value is size_t, which is not the same size as int on 64-bit platforms, you would want to either cast the result explicitly or pass printf() the z type specifier:



                  #include <stddef.h>

                  /* ... */

                  constexpr size_t offset_c = offsetof( Foo, c );
                  printf( "%zun", offset_c );
                  cout << offset_c << 'n';


                  Whatever you were trying to do, if your compiler didn’t warn you about the type mismatch, you ought to turn on more warnings. This is especially true for someone coding by trial and error until the program compiles.






                  share|improve this answer













                  In addition to the more literal answer about why the compiler interpreted your code the way it did: you seem to have an XY problem You’re trying to format a pointer-to-member as an integer, which strongly suggests you meant to do something different.



                  If what you wanted was an int value stored in .c, you either need to create an instance Foo some_foo; and take some_foo.c, or else you need to declare Foo::c a static member, so there’s one unambiguous Foo::c across the entire class. Do not take the address in this case.



                  If what you wanted was to take an address of the .c member of some Foo, you should do as above so that Foo::c is static and refers to one specific variable, or else declare an instance and take its .c member, then take the address. The correct printf() specifier for an object pointer is %p, and to print an object pointer representation with <iostream>, convert it to void*:



                  printf( "%pn", &some_foo.c );
                  std::cout << static_cast<void*>{&some_foo.c} << 'n';


                  If what you want is the offset of Foo::c within class Foo, you want the offsetof() macro in <stddef.h>. Since its return value is size_t, which is not the same size as int on 64-bit platforms, you would want to either cast the result explicitly or pass printf() the z type specifier:



                  #include <stddef.h>

                  /* ... */

                  constexpr size_t offset_c = offsetof( Foo, c );
                  printf( "%zun", offset_c );
                  cout << offset_c << 'n';


                  Whatever you were trying to do, if your compiler didn’t warn you about the type mismatch, you ought to turn on more warnings. This is especially true for someone coding by trial and error until the program compiles.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 6 hours ago









                  DavislorDavislor

                  8,92511227




                  8,92511227






















                      uu dd is a new contributor. Be nice, and check out our Code of Conduct.










                      draft saved

                      draft discarded


















                      uu dd is a new contributor. Be nice, and check out our Code of Conduct.













                      uu dd is a new contributor. Be nice, and check out our Code of Conduct.












                      uu dd is a new contributor. Be nice, and check out our Code of Conduct.
















                      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%2f55161182%2fwhy-are-the-outputs-of-printf-and-stdcout-different%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 did Captain America manage to do this?

                      迪纳利

                      南乌拉尔铁路局