Why are the outputs of printf and std::cout different2019 Community Moderator ElectionWhat is the difference between #include <filename> and #include “filename”?What are the differences between a pointer variable and a reference variable in C++?Why can templates only be implemented in the header file?Why is “using namespace std” considered bad practice?C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Why are elementwise additions much faster in separate loops than in a combined loop?Why is it faster to process a sorted array than an unsorted array?Why does this output of the same expression from printf differ from cout?Why does printf and cout gives different output for this code?C++ difference in behavior between cout and printf
A Cautionary Suggestion
Are ETF trackers fundamentally better than individual stocks?
How could a scammer know the apps on my phone / iTunes account?
Why no Iridium-level flares from other satellites?
Why do passenger jet manufacturers design their planes with stall prevention systems?
Most cost effective thermostat setting: consistent temperature vs. lowest temperature possible
Describing a chess game in a novel
Are Roman Catholic priests ever addressed as pastor
How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?
Official degrees of earth’s rotation per day
How to write cleanly even if my character uses expletive language?
Do the common programs (for example: "ls", "cat") in Linux and BSD come from the same source code?
Print a physical multiplication table
Bacteria contamination inside a thermos bottle
Life insurance that covers only simultaneous/dual deaths
Have the tides ever turned twice on any open problem?
Python if-else code style for reduced code for rounding floats
Why one should not leave fingerprints on bulbs and plugs?
How to make healing in an exploration game interesting
Convergence in probability and convergence in distribution
Violin - Can double stops be played when the strings are not next to each other?
Is it normal that my co-workers at a fitness company criticize my food choices?
Is it true that good novels will automatically sell themselves on Amazon (and so on) and there is no need for one to waste time promoting?
Instead of a Universal Basic Income program, why not implement a "Universal Basic Needs" program?
Why are the outputs of printf and std::cout different
2019 Community Moderator ElectionWhat is the difference between #include <filename> and #include “filename”?What are the differences between a pointer variable and a reference variable in C++?Why can templates only be implemented in the header file?Why is “using namespace std” considered bad practice?C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Why are elementwise additions much faster in separate loops than in a combined loop?Why is it faster to process a sorted array than an unsorted array?Why does this output of the same expression from printf differ from cout?Why does printf and cout gives different output for this code?C++ difference in behavior between cout and printf
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++
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.
add a comment |
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++
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.
22
main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]
– YesThatIsMyName
2 days ago
7
@YesThatIsMyName -- the value ofcdoesn't matter. The code prints out the value of the pointer-to-memberFoo::c.
– Pete Becker
2 days ago
@Angew -- I was replying to a comment that has now been deleted. It said thatFoo::chadn't been initialized.
– Pete Becker
yesterday
@Angew -- thank you for your input.
– Pete Becker
yesterday
add a comment |
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++
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++
c++
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.
edited 2 days ago
kvantour
9,44431731
9,44431731
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 2 days ago
uu dduu dd
19515
19515
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.
22
main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]
– YesThatIsMyName
2 days ago
7
@YesThatIsMyName -- the value ofcdoesn't matter. The code prints out the value of the pointer-to-memberFoo::c.
– Pete Becker
2 days ago
@Angew -- I was replying to a comment that has now been deleted. It said thatFoo::chadn't been initialized.
– Pete Becker
yesterday
@Angew -- thank you for your input.
– Pete Becker
yesterday
add a comment |
22
main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]
– YesThatIsMyName
2 days ago
7
@YesThatIsMyName -- the value ofcdoesn't matter. The code prints out the value of the pointer-to-memberFoo::c.
– Pete Becker
2 days ago
@Angew -- I was replying to a comment that has now been deleted. It said thatFoo::chadn't been initialized.
– Pete Becker
yesterday
@Angew -- thank you for your input.
– Pete Becker
yesterday
22
22
main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]– YesThatIsMyName
2 days ago
main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]– YesThatIsMyName
2 days ago
7
7
@YesThatIsMyName -- the value of
c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.– Pete Becker
2 days ago
@YesThatIsMyName -- the value of
c doesn't matter. The code prints out the value of the pointer-to-member Foo::c.– Pete Becker
2 days ago
@Angew -- I was replying to a comment that has now been deleted. It said that
Foo::c hadn't been initialized.– Pete Becker
yesterday
@Angew -- I was replying to a comment that has now been deleted. It said that
Foo::c hadn't been initialized.– Pete Becker
yesterday
@Angew -- thank you for your input.
– Pete Becker
yesterday
@Angew -- thank you for your input.
– Pete Becker
yesterday
add a comment |
3 Answers
3
active
oldest
votes
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.
You know member-pointers have to take into account the possibility of virtual inheritance?
– Deduplicator
2 days ago
1
@Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent ofvoid*, each class has its own unique types of member pointers. Evensizeof(int Foo::*)may depend onFoo.
– MSalters
2 days ago
1
@MSalters No. You can have and use aint Foo::*perfectly fine whileFoois 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
2 days 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
2 days ago
2
@StoryTeller: and yet we havestd::is_member_pointer:)
– geza
2 days ago
|
show 4 more comments
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.
add a comment |
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.
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
You know member-pointers have to take into account the possibility of virtual inheritance?
– Deduplicator
2 days ago
1
@Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent ofvoid*, each class has its own unique types of member pointers. Evensizeof(int Foo::*)may depend onFoo.
– MSalters
2 days ago
1
@MSalters No. You can have and use aint Foo::*perfectly fine whileFoois 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
2 days 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
2 days ago
2
@StoryTeller: and yet we havestd::is_member_pointer:)
– geza
2 days ago
|
show 4 more comments
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.
You know member-pointers have to take into account the possibility of virtual inheritance?
– Deduplicator
2 days ago
1
@Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent ofvoid*, each class has its own unique types of member pointers. Evensizeof(int Foo::*)may depend onFoo.
– MSalters
2 days ago
1
@MSalters No. You can have and use aint Foo::*perfectly fine whileFoois 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
2 days 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
2 days ago
2
@StoryTeller: and yet we havestd::is_member_pointer:)
– geza
2 days ago
|
show 4 more comments
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.
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.
edited 2 days ago
answered 2 days ago
gezageza
13.6k33178
13.6k33178
You know member-pointers have to take into account the possibility of virtual inheritance?
– Deduplicator
2 days ago
1
@Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent ofvoid*, each class has its own unique types of member pointers. Evensizeof(int Foo::*)may depend onFoo.
– MSalters
2 days ago
1
@MSalters No. You can have and use aint Foo::*perfectly fine whileFoois 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
2 days 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
2 days ago
2
@StoryTeller: and yet we havestd::is_member_pointer:)
– geza
2 days ago
|
show 4 more comments
You know member-pointers have to take into account the possibility of virtual inheritance?
– Deduplicator
2 days ago
1
@Deduplicator: Only for classes that use virtual inheritance, of course. There's no member pointer equivalent ofvoid*, each class has its own unique types of member pointers. Evensizeof(int Foo::*)may depend onFoo.
– MSalters
2 days ago
1
@MSalters No. You can have and use aint Foo::*perfectly fine whileFoois 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
2 days 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
2 days ago
2
@StoryTeller: and yet we havestd::is_member_pointer:)
– geza
2 days ago
You know member-pointers have to take into account the possibility of virtual inheritance?
– Deduplicator
2 days ago
You know member-pointers have to take into account the possibility of virtual inheritance?
– Deduplicator
2 days 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
2 days 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
2 days ago
1
1
@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
2 days 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
2 days 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
2 days 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
2 days ago
2
2
@StoryTeller: and yet we have
std::is_member_pointer :)– geza
2 days ago
@StoryTeller: and yet we have
std::is_member_pointer :)– geza
2 days ago
|
show 4 more comments
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.
add a comment |
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.
add a comment |
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.
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.
edited 2 days ago
answered 2 days ago
StoryTellerStoryTeller
102k12215278
102k12215278
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered 2 days ago
DavislorDavislor
8,95511227
8,95511227
add a comment |
add a comment |
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.
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
22
main.cpp:22:27: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int Foo::*’ [-Wformat=]– YesThatIsMyName
2 days ago
7
@YesThatIsMyName -- the value of
cdoesn't matter. The code prints out the value of the pointer-to-memberFoo::c.– Pete Becker
2 days ago
@Angew -- I was replying to a comment that has now been deleted. It said that
Foo::chadn't been initialized.– Pete Becker
yesterday
@Angew -- thank you for your input.
– Pete Becker
yesterday