C++ function pointers and presetting arguments - c++

Say I have a function f(a, b, c). Is it possible to create function pointers g and h such that when you use g and h they use a predetermined value for one of the arguments?
For example (*g)(b, c) would be equivalent to f(1, b, c) and (*h)(b, c) would be equivalent to calling f(2, b, c).
The reason why I am doing this is that I am calling a function to which I can obtain a pointer (through dlsym) and this function has drastically different behaviour depending on what the first argument is (so much so that they shouldn't really be called the same thing). What's more the function pointer variable that is being used in the main program can only generally take two arguments as this is a special case where the imported function has three (but really only two are necessary, one is essentially a settings parameter).
Thanks.

I don't see why you can do this if you have defined the function g points to as
void gfunc(int b, int c) {
f (1, b, c);
}
g = &gfunc;
The better way to do this in C++ is probably using functors.

Related

Function call syntax through a pointer dereference

Consider the code
int add(int a, int b)
{
return a + b;
}
int main()
{
std::cout << (*add)(3, 2);
}
What is the point of dereferencing the function pointer ???
I can't think of such a use case where it would give an advantage ...
Why this function call syntax exists in C++ ?
This syntax exists because C had it, and C++ syntax was originally based on C.
There is no difference in the code behaviour of f(args) and (*f)(args).
I can't be sure if I am right, but here is a possible explanation:
Every function in c and as well as in c++ is a potential variable.
Possible declaration of function is:
int (*MyFunction)(int, double);
In this case- Variable name: MyFunction | Type: function that returns int with int, double parameters.
So, even when you declare function, you actually declare variable with a "function" type. In this case, it is make sense why can you use, in your case (*add)(3, 2) for function calling (or using a variable).
It may by more clearly for you to have a look on lambda expressions, which can make a function implementation, and then let you use it like a local function variable:
int(*MyFunction)(int, double) = [](int a, double b) -> int {
return (int)((a + b) * 10);
};
Here we declare on function type variable, and implement a function for it with a lambda expression. Now we can use it in two forms:
MyFunction(1, 2.5); // Like a regular function
(*MyFunction)(1, 2.5); // As a function type variable
Again, it is the most sense explanation that I could think of. I don't sure if it is a right/best/fully explanation, but I hope it gave you a new perspective of functions.

Why are the default arguments provided for trailing arguments only [duplicate]

Why should default parameters be added last in C++ functions?
To simplify the language definition and keep code readable.
void foo(int x = 2, int y);
To call that and take advantage of the default value, you'd need syntax like this:
foo(, 3);
Which was probably felt to be too weird. Another alternative is specifying names in the argument list:
foo(y : 3);
A new symbol would have to be used because this already means something:
foo(y = 3); // assign 3 to y and then pass y to foo.
The naming approach was considered and rejected by the ISO committee because they were uncomfortable with introducing a new significance to parameter names outside of the function definition.
If you're interested in more C++ design rationales, read The Design and Evolution of C++ by Stroustrup.
If you define the following function:
void foo( int a, int b = 0, int c );
How would you call the function and supply a value for a and c, but leave b as the default?
foo( 10, ??, 5 );
Unlike some other languages (eg, Python), function arguments in C/C++ can not be qualified by name, like the following:
foo( a = 10, c = 5 );
If that were possible, then the default arguments could be anywhere in the list.
Imagine you had a function with this prototype:
void testFunction(bool a = false, bool b = true, bool c);
Now suppose I called the function like this:
testFunction(true, false);
How is the compiler supposed to figure out which parameters I meant to supply values for?
As most of the answers point out, having default parameters potentially anywhere in the parameter list increases the complexity and ambiguity of function calls (for both the compiler and probably more importantly for the users of the function).
One nice thing about C++ is that there's often a way to do what you want (even if it's not always a good idea). If you want to have default arguments for various parameter positions, you can almost certainly do this by writing overloads that simply turn around and call the fully-parameterized function inline:
int foo( int x, int y);
int foo( int y) {
return foo( 0, y);
}
And there you have the equivalent of:
int foo( int x = 0, int y);
As a general rule function parameters are processed by the compiler and placed on the stack in right to left order. Therefore it makes sense that any parameters with default values should be evaluated first.
(This applieds to __cdecl, which tends to be the default for VC++ and __stdcall function declarations).
Its because it uses the relative position of arguments to find to which parameters they correspond.
It could have used the types to identify that an optional parameter was not given. But implicit conversion could interfere with it. Another problem would be programming errors that could be interpreted as optional arguments drop out instead of missing argument error.
In order to allow any argument to become optional, there should be a way to identify the arguments to make sure there is no programming error or to remove ambiguities. This is possible in some languages, but not in C++.
Another thing that the standards committee had to consider was how default parameters interacts with other features, like overloaded functions, template resolution, and name lookup. These features interact in very complex and hard to describe ways already. Making default parameters be able to appear anywhere would only increase the complexity.
It is a matter about call convention.
Call Convention:
When you call a function, the parameters are pushed in stack from right to left.
e.g.
fun(int a, int b, int c);
the stack is like this:
a
b
c
so, if you set the default value from left to right like this:
fun(int a = 1, int b = 2, int c);
and call like this:
fun(4,5);
your call means set a = 4, b = 5, and c = no value; // which is wrong!
if you declare the function like this:
fun(int a, int b = 2, int c = 3);
and call like this:
fun(4, 5);
your call means set a = 4, b = 5, and c = default value(3); // which is right!
In conclusion, you should put the default value from right to left.
Jing Zeng is correct. I would like to add my remarks here. When a function is called, the arguments are pushed onto the stack from right to left. For example, let's say you have this arbitrary function.
int add(int a, int b) {
int c;
c = a + b;
return c;
}
Here is the stack frame for the function:
------
b
------
a
------
ret
------
c
------
This diagram above is the stack frame for this function! As you can see, first b is pushed onto the stack, then a is pushed onto the stack. After that the function return address is pushed onto the stack. The function return address holds the location in main() from where the function was originally called, and after the function is done executing, the execution of the program goes to that function's return address. Then any local variables such as c are pushed onto the stack.
Now the key thing is that arguments are pushed onto the stack from right to left. Basically any default parameters that are supplied are literal values, which are stored in the code section of an executable. When the program execution encounters a default parameter without a corresponding argument, it pushes that literal value onto the top of the stack. Then it looks at a and pushes the argument's value onto the top of the stack. The stack pointer always points to the top of the stack, your most recently pushed variable. So any literal values you pushed onto the stack as default parameters are "behind" the stack pointer.
It was probably more efficient for the compiler to quickly first push arbitrary default literal values onto the stack first, since they're not stored in a memory location, and build up the stack quickly. Think about what would have been if the variables would have been pushed onto the stack first, and then the literals. Accessing a memory location for the CPU takes up a relatively long time compared to pulling a literal value out of a circuit or CPU register. Since it takes more time to push variables onto the stack vs. literals, the literals would have to wait, then the return address would have to wait, and the local variables would have to wait as well. It's probably not a big concern in efficiency, but that's just my theory for why default arguments are always in the rightmost positions of a function header in C++. It means that the compiler was designed as such.

Implementing the [B,C]=f(A) syntax (function f acting on an array with two or more output arrays)

I have a question which is an extension of other two questions I have recently posted:
Implementing B=f(A), with B and A arrays and B already defined
and
Implementing the B=f(A) syntax by move assignment
Suppose I have an array A. I want to create a function f that acts on A and returns two other arrays B and C, by enabling the following Matlab-like syntax
[B,C]=f(A);
Is it possible in C++?
SOLUTION FOLLOWING LEEMES' ANSWER
#include <tuple>
using std::tie;
std::tuple<TypeOfB,TypeOfC> f(const Matrix<T1>&a,const Matrix<T2>&a) {
// Instruction declaring and defining B_temp and C_temp
return std::make_tuple(B_temp,C_temp); }
int main( int argc, char** argv)
{
// Instruction declaring A, B and C
tie(B,C)=f(A);
// STUFF
return 0;
}
Everything works also when changing std::tuple and make_tuple to std::pair and std::make_pair for this particular case (only two outputs).
In general, if you want to return multiple values, you have to do some little work-around, since C++ doesn't allow this out of the box.
The first option is to return a std::pair containing both values. Then you can use std::tie in a return statement if you have C++11 available, like this:
std::tie(B, C) = f(A);
(Note: C++11 also has std::tuple for more than two values.)
Or you can pass the two target variables by reference, but then the function call becomes something like this (works without C++11):
f(A, B, C);
To make the function call look more "verbose" (some people don't like that you can't tell that f changes B and C from looking at this single line of code) you can also use pointers instead of references. Then the function call would look like this:
f(A, &B, &C);
Another option is to use a simple "container" for your multiple return values. This is useful in particular if a simple pair or tuple don't give the values a particular meaning. The best option is to use this consistently in the code which calls f (don't use separate arrays B and C). Use this only if it fits nicely into the rest of your code design.
struct TwoArrays {
int B[100];
int C[100];
};
TwoArrays result = f(A);

creating functions with default parameters between non-default parameters in C++

My employer company has an API package & I am asked to create a test for QA using a certain function of a class. The function is something like this:
void func(int a, int b, int c, int d, int e);
where b & d are default parameters. The types are obviously not int, I have created them here for understanding purpose. Currently I can use that function by passing NULL for the default args. But I was thinking in the case of above function func, if the default value for b & d was non-zero say 1 & the user did not know this & if he used NULL (which is = 0) then a different result would be arrived.
So I would like to know how should I create such functions that have default args between non-default ones & I should not be needed to pass anything for that arg i.e.
func(23, , 34, , 45);
Currently VS2010 is giving me compile error for similar implementation for our company's API call.
I hope I made the question pretty clear to understand.
I tried searching similar question elsewhere too but could not find solution for my query.
Thank You.
You can't do that, you have to put all non-optional parameters first, followed by optional parameters after.
You can read a bit more about optional parameters here. Microsoft says:
Default arguments are used only in function calls where trailing arguments are omitted — they must be the last argument(s). Therefore, the following code is illegal:
int print( double dvalue = 0.0, int prec );
void func(int a, int c, int e)
{
int default_b = 1;
int default_d = 1;
func(a, default_b, c, default_d, e);
}
Otherwise you simply can't, as there is no named parameters in C++.
(Though another solution would be to use boost::bind or a similar functor).
If you can modify the original function, you can simply use default value at the condition the defaulted parameter are at the end :
void func(int a, int c, int e, int b = 1, int d = 1);
How do you expect the compiler to know that you mean to pass a,c and e and not some other triplet? In a function declaration all parameters after a parameter with default value should have default values. So you can never have default b and d - whenever you pass only three parameters to this function it would mean you want to use the default values for the last 2 parameters and these are d and e. Move your optional parameters as last in the function.
There is no direct way to achieve what you are looking for.
The first alternative would be the use of boost::optional<T> for the parameters.
Another alternative might be named parameters, as implemented in the Boost Parameter Library.
If you think that this might be something for you and you want further elaboration on how these could be used for your use case, let me know and I'll edit this answer.
There is a boost library for this boost::parameter http://www.boost.org/doc/libs/1_53_0/libs/parameter/doc/html/index.html
It supports named parameters in arbitrary order with default values for non used parameters.

Parameters by reference to a C function

I want to pass a value by reference in C. Are this two functions the same? Which is the difference? Is the same in C++?
void foo1(int * val1, int * val2)
void foo2(int &val1, int &val2)
Thanks,
References are C++ only (not C).
The implementations of the methods will be different, since dereferencing a reference is different from dereferencing a pointer in C++.
e.g.
ref.method();
vs.
ptr->method();
In both cases you're calling on the original object passed to the method, not a copy.
The second is not C, only C++. Passing by reference is in C emulated by passing the addresses of the values.
In C you can not do foo2, because there is no reference operator like in C++.
In C++ they are not the same either. References can not be NULL and they are constant. They can not point to another location after initialisation.
void foo1(int * val1, int * val2) is equivalent of
void foo2(int &val1, int &val2) in C. In both the case functions need addresses.
The 2nd one is used in C++. This can be used to pass the reference of any variable.
For example if you have a variable like int num1 = 10, num2 = 20; .
Then foo2(&num1 , &num2 ) needs foo2 in C++ but this will not work in C.
In C, there is no pass by reference. Instead you can pass the addresses to pointers, which essentially allows one to change the value of the variable passed.
The second function is in C++.
The two functions have a different signature, although they allow one to perform the same task.