void execute(int &x,int y=100)
{
x=x+y;
cout<<x<<endl;
}
void main()
{
int a=5,b=6;
execute(b);
}
will the following program work in spite of not assigning a default value to the x(formal parameters in the function prototype).
Yes, it will work. By not assigning the default value to x you are forcing the caller to pass a value as the parameter. When you do execute(b) in main you are binding the reference x with actual parameter 'b' and since you have not passed any value to variable 'y' the default value will be used.
Firstly, there's no such thing as "function prototype" in C++. "Prototype" is a term from C parlance, which has no meaningful application in C++. What you have here is a function declaration, which also happens to be a function definition.
Secondly, it appears you are asking whether it is required to specify default arguments for all function arguments in C++, right? If so, the answer is no, there's no requirement to specify default arguments for all function arguments.
Thirdly, it is supposed to be int main, not void main.
You run execute(b), meaning that execute will run b = b + 100 (y is 100 since you didn't pass it in, and it got the default value), print out 106 and b will be modified back in main, since it's taken by reference.
I think you're confused as to how a function works. You're passing the value for x into it (well, a reference to an int not the actual value) so ... yes, that works.
By providing a default value for y ( int y=100 ) you're making it so the function can be called without passing the second argument to it. If called with a single argument, y will be assigned the value 100.
int a=5,b=6;
execute(b);
Once inside execute(), the initial value of x is 6, and y is 100.
Related
What is/are the difference(s) between output parameters and return values? I've looked everywhere and I can't seem to find a simple definition for either.
The return value is something well defined in C++; for instance, x in return x; is the return value, whereas int in the function declaration int myfunc() is the return type.
The concpet of output paramters is not defined in C++. However someone would interpret it as either of the following:
function parameters passed by non-const reference, as long as you actually modify it in the function, otherwise why would you call it output? An example is x in the following function declaration: void myfunc(int& x);
function parameters passed by (not necessarily const) pointer to non-const, like x in both the following function declarations: void fun1(int * x) and void fun2(int * const x);
concerning this latter case, it allows "encoding" a missing parameter in as a nullptr default value, as in void fun3(int * x = nullptr).
A first difference is aesthetic: which one you like the most?
Another one is that the former concept and syntax help you convey the message that the function is giving back a value, something which is clear at the call site too (whereas at the call site you might not know if a parameter corresponding to an argument is passed by reference or not).
There are several differences between this two ways a function can have "consequences" at the caller site. For instance, you can only have one return value, whereas you can have as many paramters as you like.
Performancewise, complier optimizations can minimize the difference in performance, and maybe you should not worry (yet) about it.
I am well aware that modifying a function's argument that is passed by value is ineffective outside of the C/C++ function, but compilers allow it - but what happens? Is a local copy made of the argument and that is modifiable within the function?
#include <stdio.h>
void doSomething( int x )
{
x = 42;
printf( "The answer to Life, the Universe and Everything is (always): %i!\n", x );
}
int main( int argc, char **argv )
{
int a = 0;
doSomething( a );
return -a;
}
Now this always exits without error, but where in the scheme of things (memory space) is the value represented in the function as x kept?
I imagine that should the (combined declaration and definition) begin:
void doSomething( const int x )
I would get my wrists slapped by any half-decent compiler.
For the function doSomething(), x is local to the function. It has the similar scope of any other variable defined at the beginning of the function body.
In general terms, x exists only in the scope of doSomething() function. x is defined once doSomething() is called (and the argument is passed) and destroyed once the control returns. As long as the function call is being executed (i.e., the variable remains in scope), the parameter(s) are the same as any other variable, only initialized by the arguments supplied in the function call.
Quoting C11, chapter ยง6.2.1, Scopes of identifiers
[...] If the declarator or type specifier that
declares the identifier appears inside a block or within the list of parameter declarations in
a function definition, the identifier has block scope, which terminates at the end of the
associated block. [...]
As you are already aware, x being the local copy of the actual argument passed to function call, any changes made to x inside the function will not reflect into the caller (actual argument), but there's no reason for the compiler to complain as long as the operation(s) on x inside the function is (are) valid.
As others have explained, x is local in function doSomething, any modifications only affect the local copy of the argument.
Note however that C++ allows passing by reference: a very small change in the definition of doSomething() would have significant consequences for this program:
void doSomething( int& x ) {
x = 42;
printf( "The answer to Life, the Universe and Everything is (always): %i!\n", x );
}
With the above function definition, variable a in main would indeed have its value changed to 42. Since the code in main() is identical, this C++ feature can lead to confusing code, especially for a C programmer.
A value parameter of a function is effectively a local variable of the function, except that it is initialised in the function call. So these:
void f( int n ) {
n++;
}
and:
void g() {
int n = 0;
n++;
}
are effectively the same, if the call to f() was made as f(0). In both cases, the variable will be discarded on function exit.
The formal parameter x is a separate object in memory from the actual parameter a, so any changes to x are not reflected in a.
Value x is local and is kept in stack. Each function has it own part of stack which is reserved when program enters function.
Value x will be located in this part of stack. And it is valid only in scope of function which defined it.
If you change x it will be changed only for function where it is defined.
if function ends (return from function), stack which was reserved for function is destroyed so also value x. So x won't be accessible because it doesn't exists anymore.
In this code I change iType variable which is a function parameter. It works fine, but is it correct?
void ImgCoreQCV::IPThreshold( double dThresh, double dMaxval, int iType, bool bTreshOtsu ) {
if(bTreshOtsu)
iType |= THRESH_OTSU;
if(undoVector.back().channels()!=1)
cvtColor(undoVector.back(),CurImg,CV_BGR2GRAY);
threshold(CurImg,CurImg,dThresh,dMaxval,iType);
}
I mean that I did not create a new variable and has changed it:
int iThreshType = iType;
if(bTreshOtsu)
iThreshType = iType | THRESH_OTSU;
threshold(CurImg,CurImg,dThresh,dMaxval,iThreshType);
It is correct in this particular case, and it has no side effect since the argument here is a copy of the actual parameter passed.
But it might make a trouble in general case, if you unintentially change parameter passed by reference.
Also modifying parameters usually make the code worse readable. And might require more time for understanding what is really happening in the function.
So, generally I wouldn't recommend modifying parameters. Leave this optimization to the compiler.
As long you don't have by reference parameters, changing the value won't have any effect outside of your function.
It's fine to do so and you don't need a extra variable.
You can create a temporary variable inline of the lowest function call like this:
threshold(CurImg,CurImg,dThresh,dMaxval, bTreshOtsu ? iType|THRESH_OTSU : iType);
There are a couple of things that you should be clear on regarding function parameters:
void IPThreshold( double dThresh, double dMaxval, int iType, bool bTreshOtsu );
The above function will pass copies of each of the parameter values to the function body. When invoked with a local variable then the value of the local variable is unchanged after you modify it in the function.
void IPThreshold( double& dThresh, double& dMaxval, int& iType, bool bTreshOtsu );
Above the function will use non-const references which means that you can modify the value of the referenced parameter within the function. If you call this version with a local variable and you modify the parameter then the local variable will be modified after the call returns.
You also ask if this is okay... well I personally attempt not to use parameters for this if I can avoid it as I think that return values are generally clearer. However there is nothing wrong with it. The only caveat I would say is that you should be consistent with the meaning of how you pass your parameters.
When I pass a variable by reference like this:
void function(int &r){
//do something
}
int main(){
int a = 100;
function(a);
return 0;
}
What actually happens ? Does r contain the address of an integer variable or something ? How does it find it ?
Reference of your integer a will be passed as argument to your function. Now in your function, if you change the value pointed by r, it will be reflected in a as well.
So if you assign r=2 in your function and print out a in main, you will see that a has the value 2.
Your program has some syntax errors, but I can understand what you wanted to convey.
Edit:
From the user perspective, it's as if you were receiving a value in the function except that modification done to it are visible from the caller. It's also cheaper in terms of performance when passing big objects because no copy is needed.
How it works in practice is that the compiler actually pass a pointer to the function. But since the caller must have a valid object to pass to the function, a reference can't be invalid contrary to a pointer so you don't need to check for NULL values.
While going through some allegro tutorials I found an odd call.
int al_init();
The function al_init() initializes allegro so that the allegro functions can be used. What is with the int al_init(); line? If I change this line of the code to exclude int it works the same, but if I take out the line altogether it does not work. What is this line doing? The only thing I can imagine is that it creates an integer and assigns it the return value of the al_init() function, with that likely being -1 for failure and 0 for success etc. But if that is what this is doing, then how can you even check the return value?
In C/C++ there are function declarations and function definitions:
Declarations look like these:
int a_function();
void another_function();
double yet_another_function();
Explanation:
The identifier before the function name (e.g. int, void, double) describes the type of value returned by the function.
If you do not specify one, it defaults to int (which is why it works when you remove int from int al_init(), but not when you remove the declaration altogether)
void means it's not supposed to return a value (even though technically it can, but that's for rarer cases)
Definitions look like these:
int a_function() {
std::cout << "hello world!";
int x = 1;
int y = 2;
return (x + y);
}
Notice the difference:
Declarations end with ;
Definitions are followed by a block of code enclosed by braces: { and }, but no ;!
In some cases, you do not need to declare a function. If it's at a point in the code where the definition has already been seen, the definition can substitute for the declaration (this leads us to the next point...)
The purpose of declaration is to tell the program that, for example, there is a function named a_function, it expects no arguments, and it returns a value of type int.
Are you sure you aren't looking at the function declaration?
According to C's syntactic rules, a prototype is defined as:
<return-type> function-name (param1, param2, ..);
And a function call is defined as:
function-name(param1, param2,...);. So its obviously defining a function prototype and NOT calling the function.
C89 and previous rules were:
With the above rule, another rule was:
For implicit integer return type, the prototype was suppose to be defined outside of any executable function code. If it was inside of a function, it would be called a function-call and not function-prototype-definition.
That aside, lets start with the question:
While going through some allegro tutorials I found an odd call. int
al_init();
That's incorrect, it looks like a function prototype or declaration
The function al_init() initializes allegro so that the allegro
functions can be used. What is with the int al_init(); line? If I
change this line of the code to exclude int it works the same, but if
I take out the line altogether it does not work.
What does not work? Stops to compile? That would be obvious because it will not be able to find al_init() function. Also the reason it works without the "int" is because its implicitly assumed to return an integer.
What is this line doing?
Its telling the compiler that al_init() library function is defined elsewhere, typically in a .lib or .a or .dll, and you would want to use it in your program.
The only thing I can imagine is that it creates an integer and assigns
it the return value of the al_init() function,
Absolutely incorrect interpretation of code, it does not create any integer, nor assigns any value to it.
with that likely being -1 for failure and 0 for success etc. But if
that is what this is doing, then how can you even check the return
value?
Since you want to know what that function returned, you could do this while an actual call to al_init():
int retval = al_init();
printf("al_init() returned %d",retval);