Does the following result in well-defined behavior? That is, if you cast a non-vararg function f as a vararg function g and call g with the arguments that f expects, does the behavior match that of calling f with those arguments?
class Base {};
class Derived1 : public Base {
public:
int getInt1() {return 1;}
};
class Derived2 : public Base {
public:
int getInt2() {return 2;}
};
typedef int (*vfunc)(...);
int foo (vfunc f) {
Derived1 d1;
Derived2 d2;
return f(&d1, &d2);
}
int bar (Derived1 * p1, Derived2 * p2) {
return p1->getInt1() + p2->getInt2();
}
int main (int argc, char ** argv) {
return foo((vfunc)bar); // Is this program guaranteed to return 3?
}
UPDATE
Is there some way I can get the program to be well-defined, even if using proprietary keywords? Such as doing some stuff like __cdecl mentioned here:
http://msdn.microsoft.com/en-us/library/984x0h58%28v=vs.80%29.aspx
My end goal is to have a matcher function that tries matching on a list of X pointers. The matcher function takes in a predicate (not necessarily a function… might be a list) and takes in a function that it will pass the matched results to. The callback function passed to it takes the same argument types and arity as the predicate matched.
No, the behavior is undefined, per C++11 5.2.11/6 (
reinterpret_cast):The type of
barisint(Derived1*, Derived2*). The type of the function pointed to byf(the expression through which the call is made) isint(...). The two are not the same and therefore the behavior is undefined.