Why do two functions have the same address? - c++

Consider this function template:
template<typename T>
unsigned long f(void *) { return 0;}
Now, I print the addresses of f<A> and f<B> as:
std::cout << (void*)f<A> << std::endl;
std::cout << (void*)f<B> << std::endl;
Why do they print the same address if compiled in MSVS10? Are they not two different functions and therefore should print different addresses?
Updated:
I realized that on ideone, it prints the different address. MSVS10 optimizes the code, as the function doesn't depend on T in any way, so it produces same function. #Mark's answer and comments on this are valuable. :-)

You need to cast to void *:
std::cout << (void*)(ftype*)f<A> << std::endl;
std::cout << (void*)(ftype*)f<B> << std::endl;
If you cast to a function pointer (or several other classes of non-void pointers), it will be interpreted as a bool by the operator<< for std::ostream (hence the 1).

Since the function doesn't depend on the template parameter, the compiler can condense all instantiations into a single function.
I don't know why you get 1 for the address.
Added by Nawaz:
I experimented with my real code, and concluded that what #Mark said above is very important here :
Since the function doesn't depend on the template parameter, the compiler can condense all instantiations into a single function.
I also came to a conclusion that if the function-body depends on T*, not on T, it still produces the same function for different type arguments in my real code (not on ideone, though). However, if it depends on T, then it produces different functions, because sizeof(T) differs (fortunately for me) for different type arguments.
So I added a dummy automatic variable of type T in the function template, so that the function could depend on the size of T so as to force it to produce different functions.

This is simply a case of undefined behavior because the results of casting a pointer to a function to a pointer to object type are undefined.
A more interesting expression to examine would bef<A> == f<B> which should evaluate to true if and only if A and B refer to the same type.

Related

What's the purpose of std::to_integer?

As far as I know, std::to_integer<T> is equivalent to T(value) where value is a variable having type std::byte.
I looked into some implementations from the major compilers and found that in this case equivalent means literally implemented as. In other terms, most of the times to_integer is actually implemented as:
return T(value);
And that's all.
What I don't understand is what's the purpose of such a function?
Ironically the cons are even more than the pros. I should include a whole header for such a function just to avoid a C-like cast that is most likely directly inlined anyway.
Is there any other reason for that or it's just really a nice looking alternative for a C-like cast and nothing more?
it's just really a nice looking alternative for a C-like cast and nothing more?
You say that as though it's some trivial detail.
Casts are dangerous. It's easy to cast something to the wrong type, and often compilers won't stop you from doing exactly that. Furthermore, because std::byte is not an integral type in C++, working with numerical byte values often requires a quantity of casting. Having a function that explicitly converts to integers makes for a safer user experience.
For example, float(some_byte) is perfectly legal, while to_integer<float>(some_byte) is explicitly forbidden. to_integer<T> requires that T is an integral type.
to_integer is a safer alternative.
I should include a whole header for such a function
If by "whole header", you mean the same header you got std::byte from and therefore is already by definition included...
std::to_integer<T>(some_byte) is equivalent to T(some_byte) if it actually compiles. T(some_byte) is equivalent to the unsafe C-style cast of (T)some_byte, which can do scary things. On the other hand, std::to_integer is appropriately constrained to only work when it is safe:
This overload only participates in overload resolution if std::is_integral_v<IntegerType> is true.
If the T was not actually an integer type, rather than potentially having undefined behavior, the code won't compile. If the some_byte was not actually a std::byte, rather than potentially having undefined behavior, the code won't compile.
Beyond the expression of intent and safety issues already mentioned, I get the idea from the committee discussion on the paper that it’s meant to be like std::to_string and might have more overloads in the future.
A C style cast is not equivalent to std::to_integer<T>. See the below example.
std::to_integer<T> only participates in overload resolution if std::is_integral_v<T> is true.
#include <cstddef>
#include <iostream>
template <typename T>
auto only_return_int_type_foo(std::byte& b)
{
return std::to_integer<T>(b);
}
template <typename T>
auto only_return_int_type_bar(std::byte& b)
{
return T(b);
}
int main()
{
std::byte test{64};
// compiles
std::cout << only_return_int_type_foo<int>(test) << std::endl;
// compiler error
std::cout << only_return_int_type_foo<float>(test) << std::endl;
// compiles
std::cout << only_return_int_type_bar<int>(test) << std::endl;
// compiles
std::cout << only_return_int_type_bar<float>(test) << std::endl;
}

Is it safe to take the address of a temporary?

In my program, I would like to take the address of a temporary. Here is an example:
#include <iostream>
struct Number {
int value;
Number(int n) {
value = n;
}
};
void print(Number *number) {
std::cout << number->value << std::endl;
}
int main() {
Number example(123);
print(&example);
print(&Number(456)); // Is this safe and reliable?
}
This would output:
123
456
To compile, the -fpermissive flag is requied.
Here is my question: is this safe and reliable? In what possible case could something go wrong?
If your definition of "safe and reliable" includes "will compile and produce the same results if the compiler is updated" then your example is invalid.
Your example is ill-formed in all C++ standards.
This means, even if a compiler can be coerced to accept it now, there is no guarantee that a future update of your compiler will accept it or, if the compiler does accept the code, will produce the same desired effect.
Most compiler vendors have form for supporting non-standard features in compilers, and either removing or altering support of those features in later releases of the compiler.
Consider changing your function so it accepts a const Number & rather than a pointer. A const reference CAN be implicitly bound to a temporary without needing to bludgeon the compiler into submission (e.g. with command line options). A non-const reference cannot.
&Number(456) is an error because the built-in & operator cannot be applied to an rvalue. Since it is an error, it is neither safe nor reliable. "What could go wrong" is that the code could be rejected and/or behave unexpectedly by a compiler which follows the C++ Standard. You are relying on your compiler supporting some C++-like dialect in which this code is defined.
You can output the address of the temporary object in various ways. For example add a member function auto operator&() { return this; } . The overloaded operator& can be applied to prvalues of class type.
Another way would be to have a function that is like the opposite of move:
template<typename T>
T& make_lvalue(T&& n)
{
return n;
}
and then you can do print(&make_lvalue(Number(456)));
If you are feeling evil, you could make a global template overload of operator&.
This is fine but..
Number *a;
print(a); // this would be a null ptr error
How I would change it is
void print(const Number num) // make the paramater const so it doesnt change
{
std::cout << num.value << std::endl; // note the . instead of -> cuz this is a reference not a pointer
}
You would remove the "&" from your code like:
Number example(123);
print(example);
print(Number(456));
and if you need to pass a pointer you just put a "*" to dereference it.
chasester

Strange behavior in casting of function pointers in C++

I have recently encountered a behavior in C++ regarding function pointers, that I can't fully understand. I asked Google for help as well as some of my more experienced colleagues, but even they couldn't help.
The following code showcases this mystique behavior:
class MyClass{
private:
int i;
public:
MyClass(): i(0) {}
MyClass(int i): i(i) {}
void PrintText() const { std::cout << "some text " << std::endl;}
};
typedef void (*MyFunction) (void*);
void func(MyClass& mc){
mc.PrintText();
}
int main(){
void* v_mc = new MyClass;
MyFunction f = (MyFunction) func; //It works!
f(v_mc); //It works correctly!!!
return 0;
}
So, first I define a simple class that will be used later (especially, it's member method PrintText). Then, I define name object void (*) (void*) as MyFunction - a pointer to function that has one void* parameter and doesn't return a value.
After that, I define function func() that accepts a reference to MyClass object and calls its method PrintText.
And finally, magic happens in main function. I dynamically allocate memory for new MyClass object casting the returned pointer to void*. Then, I cast pointer to func() function to MyFunction pointer - I didn't expect this to compile at all but it does.
And finally, I call this new object with a void* argument even though underlying function (func()) accepts reference to MyClass object. And everything works correctly!
I tried compiling this code with both Visual Studio 2010 (Windows) and XCode 5 (OSX) and it works in the same manner - no warnings are reported whatsoever. I imagine the reason why this works is that C++ references are actually implemented as pointers behind the scenes but this is not an explanation.
I hope someone can explain this behavior.
The formal explanation is simple: undefined behaviour is undefined. When you call a function through a pointer to a different function type, it's undefined behaviour and the program can legally do anything (crash, appear to work, order pizza online ... anyting goes).
You can try reasoning about why the behaviour you're experiencing happens. It's probably a combination of one or more of these factors:
Your compiler internally implements references as pointers.
On your platform, all pointers have the same size and binary representation.
Since PrintText() doesn't access *this at all, the compiler can effectively ignore the value of mc altogether and just call the PrintText() function inside func.
However, you must remember that while you're currently experiencing the behaviour you've described on your current platform, compiler version and under this phase of the moon, this could change at any time for no apparent reason whatsoever (such as a change in surrounding code triggering different optimisations). Remember that undefined behaviour is simply undefined.
As to why you can cast &func to MyFunction - the standard explicitly allows that (with a reinterpret_cast, to which the C-style cast translates in this context). You can legally cast a pointer to function to any other pointer to function type. However, pretty much the only thing you can legally do with it is move it around or cast it back to the original type. As I said above, if you call through a function pointer of the wrong type, it's undefined behaviour.
I hope someone can explain this behavior.
The behaviour is undefined.
MyFunction f = (MyFunction) func; //It works!
It "works" because you use c-style cast which has the same effect as reinterpret_cast in this case I think. If you had used static_cast or simply not cast at all, the compiler would have warned of your mistake and failed. When you call the wrongly interpreted function pointer, you get undefined behaviour.
It's only by chance that it works. Compilers are not guaranteed to make it work. Behind the scenes, your compiler is treating the reference as a pointer, so your alternative function signature just happens to work.
I'm sorry, to me isn't clear why you call this a strange behavior, I don't see a undefined behavior that depends on moon cycle here, is the way to use function pointers in C.
Adding some debug output you may see that the pointer to the object remain the same in all the calls.
void PrintText() const { std::cout << "some text " << this << std::endl;}
^^^^
void func(MyClass& mc){
std::cout << (void *)&mc << std::endl;
^^^
void *v_mc = new MyClass;
std::cout << (void *)v_mc << std::endl;
^^^^

C++ Function passed as Template Argument vs Parameter

In C++, there are two ways of passing a function into another function that seem equivalent.
#include <iostream>
int add1(int i){ return i+1; }
int add2(int i){ return i+2; }
template <int (*T)(int) >
void doTemplate(int i){
std::cout << "Do Template: " << T(i) << "\n";
}
void doParam(int i, int (*f)(int)){
std::cout << "Do Param: " << f(i) << "\n";
}
int main(){
doTemplate<add1>(0);
doTemplate<add2>(0);
doParam(0, add1);
doParam(0, add2);
}
doTemplate accepts a function as a template argument, whereas doParam accepts it as a function pointer, and they both seem to give the same result.
What are the trade-offs between using each method?
The template-based version allows the compiler to inline the call, because the address of the function is known at compile-time. Obviously, the disadvantage is that the address of the function has to be known at compile-time (since you are using it as a template argument), and sometimes this may not be possible.
That brings us to the second case, where the function pointer may be determined only at run-time, thus making it impossible for the compiler to perform the inlining, but giving you the flexibility of determining at run-time the function to be called:
bool runtimeBooleanExpr = /* ... */;
doParam(0, runtimeBooleanExpr ? add1 : add2);
Notice, however, that there is a third way:
template<typename F>
void doParam(int i, F f){
std::cout << "Do Param: " << f(i) << "\n";
}
Which gives you more flexibility and still has the advantage of knowing at compile-time what function is going to be called:
doParam(0, add1);
doParam(0, add2);
And it also allows passing any callable object instead of a function pointer:
doParam(0, my_functor());
int fortyTwo = 42;
doParam(0, [=] (int i) { return i + fortyTwo; /* or whatever... */ }
For completeness, there is also a fourth way, using std::function:
void doParam(int x, std::function<int(int)> f);
Which has the same level of generality (in that you can pass any callable object), but also allows you to determine the callable object at run-time - most likely with a performance penalty, since (once again) inlining becomes impossible for the compiler.
For a further discussion of the last two options, also see this Q&A on StackOverflow.
Template parameters
have to be known at compile time.
lead to one function instantation for every distinct value of the parameter (so-called template bloat)
the called function is transparant to the compiler (inlining, but could lead to even more bloat, double-edged sword)
the calling function can be overloaded for particular values of the parameter, without modifying existing code
Function pointers
are passed at run time.
only lead to one calling function (smaller object code)
the called function is typically opaque to the compiler (no inlining)
the calling function needs a runtime if/switch to do special stuff for special values of the parameter, this is brittle
When to use which version: if you need speed and a lot of customization, use templates. If you need flexibility at runtime, but not in the implementation, use function pointers.
As #AndyProwl points out: if you have a C++11 compiler, function pointers are generalized to callable objects such as std::function and lambda expressions. This opens up a whole new can of worms (in a good sense).

Function References

So I was just working with function pointers and I remembered that you could do this:
void Foo()
{
}
int main()
{
void(& func)() = Foo;
func(); //::Foo();
}
The obvious advantage being that references reference valid objects (unless they're misused), or functions in this case.
The obvious disadvantages being that you can't store an array of references and can't use them for member function pointers (at least as far as I can tell).
My question: does anyone use them (i.e., function references, not function pointers), and if so, in what scenarios have you found them useful/helpful?
The only place I can see them being useful off the bat is binding a reference to a certain function when working with conditional compilation.
I've used them before to add customization to classes by passing them to the constructor in a way like the strategy pattern
Function references, unlike function pointers, make it harder to create them from an invalid source. This is useful if you are making a wrapper around a C library - the C++ code can take a callback function by reference and pass the pointer to the C library if the lbrary requires that the passed pointer must not be NULL.
It is also a convenient way to alias a function, especially in C++11 with the new auto keyword:
#include <iostream>
#include <typeinfo>
void f(int i, char c)
{
std::cout << i << ' ' << c << std::endl;
}
int main()
{
std::cout << typeid(f).name() << std::endl; //FvicE
f(0, '1');
void (*pf)(int, char) (&f); //ugly
std::cout << typeid(pf).name() << std::endl; //PFvicE
(*pf)(2, '3');
pf(4, '5'); //works, but I don't recommend it
void (&rf)(int, char) (f); //still ugly
std::cout << typeid(rf).name() << std::endl; //FvicE
rf(6, '7');
auto &af (f); //pretty, but only works in C++11
std::cout << typeid(af).name() << std::endl; //FvicE, same as above
af(8, '9');
}
I think your example usage is quite good. Because if you would use an ordinary function pointer, and you then apply the address-of operator, you would get the address of the function pointer. Using a reference to function will do the expected thing, in that it returns a pointer to the function itself.
I also can't think of many examples. Keeping function references, as you point out, has some ugly consequences. Another possibly unwanted consequence is, if kept as a class-member, your objects will be non-assignable if you don't write your own operator= and refrain from trying to re-assign the function-reference.
I think most uses of function references are implicit, much like most uses of array-references - although much more so, when you accept arguments by-reference:
template<typename T>
void do_something(T const& t) { ... }
While accepting arrays by reference has the advantage of not losing their size information, accepting functions by reference explicitly doesn't seem to have an advantage (at least as far as I can see). I suppose the existence of function references largely is justified by the idealistic view of a reference as an alias-name of some object or function, together with the fact that it allows passing functions to such templates that accept their argument by reference.
I would probably avoid using them if I wouldn't need them inevitably. Constant function pointers also provide non-reassignable callables, and will probably avoid confusions when other programmers, who possibly are not very familiar with this language niches, read your code. Worth to note that Vandervoorde & Josuttis also recommend to avoid them to reduce confusion (in their book C++ Templates - The Complete Guide).
in addition to the use as strategy (as pointed out by Robert Gould), I freqently use them at the entrance point to (template) metaprogramming. A function reference can easily be picked up by a template parameter; from this point on it can be passed through several layers of (metaprogramming) templates. Of course, this holds true for a function pointer as well, but the reference is an alias and thus communicates the intention more clearly.
To give an example: when writing a generic command dispatching system for an application, a lot of different operations need to be announced as commands. We can use a simple "builder function" as front-end for the client code. Behind the scenes, this builder function picks up the actual function signature as template parameter, derives (by template metaprogramming) the actual parameter and return type values and possibly picks the suitable specialisation to store a "memento" and an "undo functor". These functors can than be stored either as function pointers internally, or using boost or tr1 or C++11 function objects. This way, it is possible to build a type safe command invocation and "undo" system.
I've used them in a plug-in system where plug-in DLLs could be loaded/unloaded at run-time. I would look for known symbols in each DLL and cast them to function pointers.