I've posted a few pointer-related questions recently. I've tried to unite the confusion I'm suffering in this one post, so apologies if it looks familiar. The question is - why does funky() output the string whereas funkier() outputs the address? My logic tells me that the latter is what I would expect. Or is this just the way std::cout deals with things?
I notice that printf behaves the same way.
#include <iostream>
using namespace std;
void funky(const char* a);
void funkier(char* a[]);
int main() {
const char* y = "message";
funky(y);
char* z[3];
z[0] = "one";
z[1] = "two";
z[2] = "three";
funkier(z);
cin.get();
return 0;
}
void funky(const char* a) {
cout << a << endl; // prints the string.
}
void funkier(char* a[]) {
cout << a << endl; // prints the address.
}
The operator<< for std::ostream is overloaded for many different types of the right operand.
If the second operand is a const char* it is interpreted as a NUL-terminated string and printed.
If the second operand is a const void* it is printed as an address.
There are many other overloads, but these are not relevant here.
The funky() call uses the first overload.
But the funkier argument is actually a char**, which is neither of the above. But it is convertible to const void*, not to const char*, so the second overload is used.
Beware of printf()! That is a C function and it does not detect the type of the arguments. It expects you to pass the right %s or %p or whatever for each of the arguments. If you use the wrong letter, or pass the wrong argument type, you will probably get Undefined Behaviour.
char *x = "a";
printf("%s", x); //prints x as string
printf("%p", x); //prints x as pointer
printf("%d", x); //Undefined Behaviour!!!
printf("%d", (int)x); //prints the pointer value as an integer, if it fits
Related
I want to print out a function pointer using cout, and found it did not work.
But it worked after I converting the function pointer to (void *), so does printf with %p, such as
#include <iostream>
using namespace std;
int foo() {return 0;}
int main()
{
int (*pf)();
pf = foo;
cout << "cout << pf is " << pf << endl;
cout << "cout << (void *)pf is " << (void *)pf << endl;
printf("printf(\"%%p\", pf) is %p\n", pf);
return 0;
}
I compiled it with g++ and got results like this:
cout << pf is 1
cout << (void *)pf is 0x100000b0c
printf("%p", pf) is 0x100000b0c
So what does cout do with type int (*)()? I was told that the function pointer is treated as bool, is it true?
And what does cout do with type (void *)?
Thanks in advance.
EDIT: Anyhow, we can observe the content of a function pointer by converting it into (void *) and print it out using cout.
But it does not work for member function pointers and the compiler complains about the illegal conversion. I know that member function pointers is rather a complicated structure other than simple pointers, but how can we observe the content of a member function pointers?
There actually is an overload of the << operator that looks something like:
ostream & operator <<( ostream &, const void * );
which does what you expect - outputs in hex. There can be no such standard library overload for function pointers, because there are infinite number of types of them. So the pointer gets converted to another type, which in this case seems to be a bool - I can't offhand remember the rules for this.
Edit: The C++ Standard specifies:
4.12 Boolean conversions
1 An rvalue of arithmetic,
enumeration, pointer, or pointer to
member type can be converted to an
rvalue of type bool.
This is the only conversion specified for function pointers.
Regarding your edit, you can print out contents of anything by accessing it via unsigned char pointer. An example for pointers to member functions:
#include <iostream>
#include <iomanip>
struct foo { virtual void bar(){} };
struct foo2 { };
struct foo3 : foo2, foo { virtual void bar(){} };
int main()
{
void (foo3::*p)() = &foo::bar;
unsigned char const * first = reinterpret_cast<unsigned char *>(&p);
unsigned char const * last = reinterpret_cast<unsigned char *>(&p + 1);
for (; first != last; ++first)
{
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< (int)*first << ' ';
}
std::cout << std::endl;
}
You can think of a function pointer as being the address of the first instruction in that function's machine code. Any pointer can be treated as a bool: 0 is false and everything else is true. As you observed, when cast to void * and given as an argument to the stream insertion operator (<<), the address is printed. (Viewed strictly, casting a pointer-to-function to void * is undefined.)
Without the cast, the story is a little complex. For matching overloaded functions ("overload resolution"), a C++ compiler gathers a set of candidate functions and from these candidates selects the "best viable" one, using implicit conversions if necessary. The wrinkle is the matching rules form a partial order, so multiple best-viable matches cause an ambiguity error.
In order of preference, the standard conversions (and of course there also user-defined and ellipsis conversions, not detailed) are
exact match (i.e., no conversion necessary)
promotion (e.g., int to float)
other conversions
The last category includes boolean conversions, and any pointer type may be converted to bool: 0 (or NULL) is false and everything else is true. The latter shows up as 1 when passed to the stream insertion operator.
To get 0 instead, change your initialization to
pf = 0;
Remember that initializing a pointer with a zero-valued constant expression yields the null pointer.
In C++11 one could modify this behavior by defining a variadic template overload of operator<< (whether that is recommendable or not is another topic):
#include<iostream>
namespace function_display{
template<class Ret, class... Args>
std::ostream& operator <<(std::ostream& os, Ret(*p)(Args...) ){ // star * is optional
return os << "funptr " << (void*)p;
}
}
// example code:
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}
int main(){
using namespace function_display;
// ampersands & are optional
std::cout << "1. " << &fun_void_void << std::endl; // prints "1. funptr 0x40cb58"
std::cout << "2. " << &fun_void_double << std::endl; // prints "2. funptr 0x40cb5e"
std::cout << "3. " << &fun_double_double << std::endl; // prints "3. funptr 0x40cb69"
}
Casting pointers to (void*) to print them to cout is the right thing (TM) to do in C++ if you want to see their values.
Regarding your specific question,
how can we observe the content of a
member function pointers?
The answer is, other than converting them to bool to express that it points to something or it doesn't, you can't 'observer' member function pointers. At least not in a compliant way. The reason is because the standard explicitly disallows this:
4.12 footnote 57:
57) The rule for conversion of
pointers to members (from pointer to
member of base to pointer to member of
derived) appears inverted compared to
the rule for pointers to objects (from
pointer to derived to pointer to base)
(4.10, clause 10). This inversion is
necessary to ensure type safety. Note
that a pointer to member is not a
pointer to object or a pointer to
function and the rules for conversions
of such pointers do not apply to
pointers to members. In particular, a
pointer to member cannot be converted
to a void*.
For example, here is sample code:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Gizmo
{
public:
void DoTheThing()
{
return;
};
private:
int foo_;
};
int main()
{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;
Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way
bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;
return 0;
}
I note that my debugger (MSVC9) is able to tell me the actual physical address of the member function at runtime, so I know there must be some way to actually get that address. But I'm sure it is non-conformant, non-portable and probably involves machine code. If I were to go down that road, I would start by taking the address of the function pointer (eg &fn), casting that to void*, and go from there. This would also require you know the size of pointers (different on different platforms).
But I would ask, so long as you can convert the member-function pointer to bool and evaluate the existance of the pointer, why in real code would you need the address?
Presumably the answer to the last question is "so I can determine if one function pointer points to the same function as another." Fair enough. You can compare function pointers for equality:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Gizmo
{
public:
void DoTheThing()
{
return;
};
**void DoTheOtherThing()
{
return;
};**
private:
int foo_;
};
int main()
{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;
Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way
bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;
**void(Gizmo::*fnOther)(void) = &Gizmo::DoTheOtherThing;
bool same = fnOther == fn;
bool sameIsSame = fn == fn;**
return 0;
}
maybe (in one time I stay intersecting about the address of function)
one of decision )))
#include <iostream>
#include <stdlib.h>
void alexf();
int main()
{
int int_output;
printf("printf(\"%%p\", pf) is %p\n", alexf);
asm( "movl %[input], %%eax\n"
"movl %%eax, %[output]\n"
: [output] "+m" (int_output)
: [input] "r" (&alexf)
: "eax", "ebx"
);
std::cout<<"" <<std::hex<<int_output <<""<<std::endl;
return 0;
}
void alexf() { }
passing the pointer to function (&alexf) or other pointer using & use constraint r. Let gcc to use register for input argument)).
Here's a function prototype:
void foobar(char* array[]);
But how would I call this function, and with what arguments? Could someone give me a simple example?
Quoting from c-faq (as array name conversion rule to pointers is same in C and C++ both):
Since arrays decay immediately into pointers, an array is never actually passed to a function. You can pretend that a function receives an array as a parameter, and illustrate it by declaring the corresponding parameter as an array:
void f(char a[])
{ ... }
Interpreted literally, this declaration would have no use, so the compiler turns around and pretends that you'd written a pointer declaration, since that's what the function will in fact receive:
void f(char *a)
{ ... }
Therefore
void foobar(char* array[]);
is equivalent to
void foobar(char** array);
You need to pass an argumant of type char ** to this function.
Thanks for the reply and comments. Here is what I came up with and it seems to work. Not quite sure why it does, though. Could someone confirm that this is indeed 'correct' code:
void foobar(char* array[]);
void main() {
char* t[3];
t[0] = "first";
t[1] = "second";
t[2] = "third";
foobar(t);
}
void foobar(char* array[]) {
cout << *(array + 0) << endl;
cout << *(array + 1) << endl;
cout << *(array + 2) << endl;
}
The output is:
first
second
third
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void f(char **x)
{
(*x)++;
**x = 'a';
}
int main()
{
char str[]="hello";
f(&str);
cout << str << endl;
return 0;
}
Please tell me why this program is giving compilation Error.I am using the g++ compiler
Error :temp1.cpp:16:8: error: cannot convert ‘char (*)[6]’ to ‘char**’ for
argument ‘1’ to ‘void f(char**)’
Arrays can be implicitly converted to pointers, but that doesn't mean that the implicit "pointer equivalent" already exists.
You are hoping that f(&str); will implicitly create both a pointer to str and a pointer to that pointer.
This small (working) change illustrates this point:
int main()
{
char str[]="hello";
char *pstr = str; // Now the pointer extists...
f(&pstr); // ...and can have an address
cout << str << endl;
return 0;
}
You are passing pointer of constant char to the function but in function you are taking it as pointer of pointers. That is the problem. I commented out below where the problem lies.
[Off topic but N. B. : Arrays and pointers are different concept.]
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void f(char **x) //**x is pointer of pointer
{
(*x)++;
**x = 'a';
}
int main()
{
char str[]="hello";
f(&str); //You are passing pointer of constant char.
cout << str << endl;
return 0;
}
You're going to run into a serious problem with your function f since &str and &str[0] both evaluate to the same value ... as other posters have pointed out, these operations point to different types, but the actual pointer r-value will be the same. Thus in f when you attempt to double-dereference the char** pointer x, you're going to get a segfault even if you attempted something like a cast to massage the type differences and allow compilation to happen with errors. This is because you are never getting a pointer-to-pointer ... the fact that &str and &str[0] evaluate to the same pointer value means that a double-dereference acually attempts to use the char value in str[0] as a pointer value, which won't work.
Your problem is that you're treating arrays as pointers, when they're not. Arrays decay into pointers, and in this case, it doesn't. What you're passing in is a char (*)[6] when it expects a char **. Those are obviously not the same.
Change your parameter to char (*x)[6] (or use a template with a size parameter):
template <std::size_t N>
void f(char (*x)[N])
Once inside, you try to increment what x is pointing to. You can't increment an array, so use an actual pointer instead:
char *p = *x;
p++;
*p = 'a';
All put together, (sample)
template <std::size_t N>
void f(char(*x)[N])
{
if (N < 2) //so we don't run out of bounds
return;
char *p = *x;
p++;
*p = 'a';
}
To my knowledge the standard strcmp function looks something like this:
int strcmp(const char* string1, const char* string2)
{
while(*pString1++ == *pString2++)
{
if(*pString1 == 0) return 0;
}
return *pString1 - pString2;
}
My question is that wouldn't this increment the pointers passed into strcmp? In the following example it seems like it would trash the pointers and cause invalid stuff to happen.
const char* string1 = "blah";
const char* string2 = "blah";
const char* string3 = "blah";
if(strcmp(string1, string2) {doSomething();}
// Won't this make string1 = "" because it incremented the pointer to the end?
else if (strcmp(string1, string3) {doSomethingElse();}
Sorry I'm just confused because it seems like if I pass a pointer into strcmp, I shouldn't expect that pointer to suddenly hold an empty string. It seems like strcmp should take const char* const. Am I totally misunderstanding something?
Your misunderstanding is this: Arguments are passed by value (copy), but you seem to think they are passed by reference.
You could get your expected behaviour by declaring the parameters to strcmp as references, like this:
int strcmp(const char*& string1, const char*& string2)
No, the pointers string1 and string2 are local to the function (passed by value). Any changes made to them are not visible to the caller.
The pointer itself is passed by value, so although it's a pointer to something, changing it does change the local declaration only.
To be able to modify the pointer itself from the inner scope of the function you would need to have a pointer to pointer to char.
The pointers are passed by value, strcmp is using copies of the ones you send in, so the original ones aren't touched.
First, the classical obfuscated implementation of strcmp is even
simpler:
int
strcmp(char const* s1, char const* s2)
{
while ( *s1 ++ == *s2 ++ )
;
return *s1 - *s2;
}
(I would hope that no one would actually write code like this in
practice.)
As for your actual question: C++ (and C, since this is really a C
question) pass arguments by value, so any pointer that strcmp gets is
a copy; it can't possibly modify any of the pointers in the calling
code. All making the parameters char const* const would mean is that
strcmp couldn't modify its local copies of the pointers.
C++ passed parameters to functions "by value". Consider this code:
void f(int i) { i = 7; }
...
int j = 0;
f(j);
assert(j == 0);
The variable j is unrelated to the variable i. Indeed, i local to the function f. It is initialized with a copy of of j. Changes to i are never communicated to j.
Now consider this code:
void f(char *i) { i = i + 1; }
...
char *j = "Hello";
f(j);
assert(*j == 'H');
Similarly, i is initialized with a copy of j. Changes to i are never communicated back to j.
Note: One can force parameters to be initialized "by reference" thusly:
void f(int& i) { i = 7; }
...
int j = 3;
f(j);
assert(j==7);
In this case, rather than being initialized with a copy of j, i is bound to a j. But this only applies if you have & in the declaration.
Try this, your will find that they are totally different pointer.
What cause you misunderstand is that they point to the same area
#include <iostream>
using namespace std;
int strcmp2(char const *s1, char const *s2)
{
cout << "In strcmp" << endl;
cout << &s1 << " " << &s2 << endl;
cout << endl;
}
int main()
{
char a[100];
char b[100];
cout << "In main function" << endl;
cout << &a << " " << &b << endl;
cout << endl;
strcmp2(a, b);
}
I want to print out a function pointer using cout, and found it did not work.
But it worked after I converting the function pointer to (void *), so does printf with %p, such as
#include <iostream>
using namespace std;
int foo() {return 0;}
int main()
{
int (*pf)();
pf = foo;
cout << "cout << pf is " << pf << endl;
cout << "cout << (void *)pf is " << (void *)pf << endl;
printf("printf(\"%%p\", pf) is %p\n", pf);
return 0;
}
I compiled it with g++ and got results like this:
cout << pf is 1
cout << (void *)pf is 0x100000b0c
printf("%p", pf) is 0x100000b0c
So what does cout do with type int (*)()? I was told that the function pointer is treated as bool, is it true?
And what does cout do with type (void *)?
Thanks in advance.
EDIT: Anyhow, we can observe the content of a function pointer by converting it into (void *) and print it out using cout.
But it does not work for member function pointers and the compiler complains about the illegal conversion. I know that member function pointers is rather a complicated structure other than simple pointers, but how can we observe the content of a member function pointers?
There actually is an overload of the << operator that looks something like:
ostream & operator <<( ostream &, const void * );
which does what you expect - outputs in hex. There can be no such standard library overload for function pointers, because there are infinite number of types of them. So the pointer gets converted to another type, which in this case seems to be a bool - I can't offhand remember the rules for this.
Edit: The C++ Standard specifies:
4.12 Boolean conversions
1 An rvalue of arithmetic,
enumeration, pointer, or pointer to
member type can be converted to an
rvalue of type bool.
This is the only conversion specified for function pointers.
Regarding your edit, you can print out contents of anything by accessing it via unsigned char pointer. An example for pointers to member functions:
#include <iostream>
#include <iomanip>
struct foo { virtual void bar(){} };
struct foo2 { };
struct foo3 : foo2, foo { virtual void bar(){} };
int main()
{
void (foo3::*p)() = &foo::bar;
unsigned char const * first = reinterpret_cast<unsigned char *>(&p);
unsigned char const * last = reinterpret_cast<unsigned char *>(&p + 1);
for (; first != last; ++first)
{
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< (int)*first << ' ';
}
std::cout << std::endl;
}
You can think of a function pointer as being the address of the first instruction in that function's machine code. Any pointer can be treated as a bool: 0 is false and everything else is true. As you observed, when cast to void * and given as an argument to the stream insertion operator (<<), the address is printed. (Viewed strictly, casting a pointer-to-function to void * is undefined.)
Without the cast, the story is a little complex. For matching overloaded functions ("overload resolution"), a C++ compiler gathers a set of candidate functions and from these candidates selects the "best viable" one, using implicit conversions if necessary. The wrinkle is the matching rules form a partial order, so multiple best-viable matches cause an ambiguity error.
In order of preference, the standard conversions (and of course there also user-defined and ellipsis conversions, not detailed) are
exact match (i.e., no conversion necessary)
promotion (e.g., int to float)
other conversions
The last category includes boolean conversions, and any pointer type may be converted to bool: 0 (or NULL) is false and everything else is true. The latter shows up as 1 when passed to the stream insertion operator.
To get 0 instead, change your initialization to
pf = 0;
Remember that initializing a pointer with a zero-valued constant expression yields the null pointer.
In C++11 one could modify this behavior by defining a variadic template overload of operator<< (whether that is recommendable or not is another topic):
#include<iostream>
namespace function_display{
template<class Ret, class... Args>
std::ostream& operator <<(std::ostream& os, Ret(*p)(Args...) ){ // star * is optional
return os << "funptr " << (void*)p;
}
}
// example code:
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}
int main(){
using namespace function_display;
// ampersands & are optional
std::cout << "1. " << &fun_void_void << std::endl; // prints "1. funptr 0x40cb58"
std::cout << "2. " << &fun_void_double << std::endl; // prints "2. funptr 0x40cb5e"
std::cout << "3. " << &fun_double_double << std::endl; // prints "3. funptr 0x40cb69"
}
Casting pointers to (void*) to print them to cout is the right thing (TM) to do in C++ if you want to see their values.
Regarding your specific question,
how can we observe the content of a
member function pointers?
The answer is, other than converting them to bool to express that it points to something or it doesn't, you can't 'observer' member function pointers. At least not in a compliant way. The reason is because the standard explicitly disallows this:
4.12 footnote 57:
57) The rule for conversion of
pointers to members (from pointer to
member of base to pointer to member of
derived) appears inverted compared to
the rule for pointers to objects (from
pointer to derived to pointer to base)
(4.10, clause 10). This inversion is
necessary to ensure type safety. Note
that a pointer to member is not a
pointer to object or a pointer to
function and the rules for conversions
of such pointers do not apply to
pointers to members. In particular, a
pointer to member cannot be converted
to a void*.
For example, here is sample code:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Gizmo
{
public:
void DoTheThing()
{
return;
};
private:
int foo_;
};
int main()
{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;
Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way
bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;
return 0;
}
I note that my debugger (MSVC9) is able to tell me the actual physical address of the member function at runtime, so I know there must be some way to actually get that address. But I'm sure it is non-conformant, non-portable and probably involves machine code. If I were to go down that road, I would start by taking the address of the function pointer (eg &fn), casting that to void*, and go from there. This would also require you know the size of pointers (different on different platforms).
But I would ask, so long as you can convert the member-function pointer to bool and evaluate the existance of the pointer, why in real code would you need the address?
Presumably the answer to the last question is "so I can determine if one function pointer points to the same function as another." Fair enough. You can compare function pointers for equality:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Gizmo
{
public:
void DoTheThing()
{
return;
};
**void DoTheOtherThing()
{
return;
};**
private:
int foo_;
};
int main()
{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;
Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way
bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;
**void(Gizmo::*fnOther)(void) = &Gizmo::DoTheOtherThing;
bool same = fnOther == fn;
bool sameIsSame = fn == fn;**
return 0;
}
maybe (in one time I stay intersecting about the address of function)
one of decision )))
#include <iostream>
#include <stdlib.h>
void alexf();
int main()
{
int int_output;
printf("printf(\"%%p\", pf) is %p\n", alexf);
asm( "movl %[input], %%eax\n"
"movl %%eax, %[output]\n"
: [output] "+m" (int_output)
: [input] "r" (&alexf)
: "eax", "ebx"
);
std::cout<<"" <<std::hex<<int_output <<""<<std::endl;
return 0;
}
void alexf() { }
passing the pointer to function (&alexf) or other pointer using & use constraint r. Let gcc to use register for input argument)).