I have a question on the COM interfaces exposed from an application. Can I have a COM interface where some parameters have default values similar to the one allowed by C++?
Default values can be defined with interface definition in IDL and are language agnostic. A method argument can be provided with a defaultvalue attribute, and then defaultvalue attribute article on MSDN states:
The MIDL compiler accepts the following parameter ordering (from left-to-right):
Required parameters (parameters that do not have the [defaultvalue] or [optional] attributes),
optional parameters with or without the [defaultvalue] attribute,
parameters with the [optional] attribute and without the [defaultvalue] attribute,
[lcid] parameter, if any,
[retval] parameter
Note that only optional parameters can have defaultvalue attribute. This makes sense as non-optional parameter always comes with explicit value. This also means that any parameter having default value is actually a VARIANT parameter (effectively this is not true though: IDL compiler accepts defaultvalue attribute on non-VARIANT parameters).
Parameters with default values have restrictions on types:
The default value you specify for the parameter can be any constant, or an expression that resolves to a constant, that can be represented by a VARIANT. Specifically, you cannot apply the [defaultvalue] attribute to a parameter that is a structure, an array, or a SAFEARRAY.type.
Information about the default value stays on the IDL and the respective type library. It is the responsibility of the caller to read it and substitute at the time of the call. C++ clients #import'ing the type library will have to supply the value explicitly anyway. C# client adding such type library as a reference will extract default value and translate it into optional parameter with this default value and then will use it on the caller side of the call in such way that server sees no difference whether this value is default or explicitly given.
On the implementation side, a parameter with default value is identical to regular parameter with no default value defined: the actual value is always provided by the caller.
Related
I am working on another persons C++ code and don't understand why they did something.
They have a notification class that has a public method called check which takes in the time as a parameter
void check(unsigned long time = 1);
Every time the method is called in the code a current time is passed to it.
notification1.check(currentTime);
My question is why did they give the parameter a value when they defined the method? Why not just say,
void check(unsigned long time);
That's because if no argument if provided in function call, default argument value will be used for time which is 1 in this case. This is called Default Argument
If you call check function and provide no argument, default value of 1 will be assigned to time by the compiler. If you pass an argument while calling check function, that passed value will override the default value of time.
When a function has a default argument passed in to it, you are not required to pass an argument while calling that function and you can specify as many default arguments as you want.
Do you have access to the implementation of check function?
since there is default argument specified in function declaration, you can call it without arguments as well. (ex: notification1.check() ) you should explore what is the behaviour of the check(...) function in each of following scenarios
Function call WITH an argument? (i.e. notification1.check(currentTime))?
Function call WITHOUT argument? (i.e. notification1.check())?
As a best practice of coding, these behaviours has to be documented with the member function declaration. if it is not the case, you'll have to explore the implementation.
It's a default argument. http://en.cppreference.com/w/cpp/language/default_arguments explains all you ever wanted to know about this C++ feature.
My question is why did they give the parameter a value when they defined the method?
If the default argument is not used anywhere, i.e. if the function is always called with a non-default argument, then chances are it was a wrong design decision. Perhaps they thought the default argument was useful when they originally designed the code, but it now turned out that there is no useful default value. Or perhaps they think that the default argument may still be useful in the future.
As a matter of fact, 1 is a questionable value for an unsigned long time parameter, which looks a lot like a value representing milliseconds since January 1st 1970. Why not 0?
In Kotlin there are two ways to express an optional parameter, either by specifying default argument value:
fun foo(parameter: Any, option: Boolean = false) { ... }
or by introducing an overload:
fun foo(parameter: Any) = foo(parameter, false)
fun foo(parameter: Any, option: Boolean) { ... }
Which way is preferred in which situations?
What is the difference for consumers of such function?
In Kotlin code calling other Kotlin code optional parameters tend to be the norm over using overloads. Using optional parameters should be you default behavior.
Special cases FOR using defaulted values:
As a general practice or if unsure -- use default arguments over overrides.
if you want the default value to be seen by the caller, use default values. They will show up in IDE tooltips (i.e. Intellij IDEA) and let the caller know they are being applied as part of the contract. You can see in the following screenshot that calling foo() will default some values if values are omitted for x and y:
Whereas doing the same thing with function overloads hides this useful information and just presents a much more messy:
using default values causes bytecode generation of two functions, one with all parameters specified and another that is a bridge function that can check and apply missing parameters with their defaulted values. No matter how many defaulted parameters you have, it is always only two functions. So in a total-function-count constrained environment (i.e. Android), it can be better to have just these two functions instead of a larger number of overloads that it would take to accomplish the same job.
Cases where you might not want to use default argument values:
When you want another JVM language to be able to use the defaulted values you either need to use explicit overloads or use the #JvmOverloads annotation which:
For every parameter with a default value, this will generate one additional overload, which has this parameter and all parameters to the right of it in the parameter list removed.
You have a previous version of your library and for binary API compatibility adding a default parameter might break compatibility for existing compiled code whereas adding an overload would not.
You have a previous existing function:
fun foo() = ...
and you need to retain that function signature, but you also want to add another with the same signature but additional optional parameter:
fun foo() = ...
fun foo(x: Int = 5) = ... // never can be called using default value
You will not be able to use the default value in the 2nd version (other than via reflection callBy). Instead all foo() calls without parameters still call the first version of the function. So you need to instead use distinct overloads without the default or you will confuse users of the function:
fun foo() = ...
fun foo(x: Int) = ...
You have arguments that may not make sense together, and therefore overloads allow you to group parameters into meaningful coordinated sets.
Calling methods with default values has to do another step to check which values are missing and apply the defaults and then forward the call to the real method. So in a performance constrained environment (i.e. Android, embedded, real-time, billion loop iterations on a method call) this extra check may not be desired. Although if you do not see an issue in profiling, this might be an imaginary issue, might be inlined by the JVM, and may not have any impact at all. Measure first before worrying.
Cases that don't really support either case:
In case you are reading general arguments about this from other languages...
in a C# answer for this similar question the esteemed Jon Skeet mentions that you should be careful using defaults if they could change between builds and that would be a problem. In C# the defaulting is at the call site, whereas in Kotlin for non-inlined functions it is inside of the (bridge) function being called. Therefore for Kotlin it is the same impact for changing hidden and explicit defaulting of values and this argument should not impact the decision.
also in the C# answer saying that if team members have opposing views about use of defaulted arguments then maybe don't use them. This should not be applied to Kotlin as they are a core language feature and used in the standard library since before 1.0 and there is no support for restricting their use. The opposing team members should default to using defaulted arguments unless they have a definitive case that makes them unusable. Whereas in C# it was introduced much later in the life cycle of that language and therefore had a sense of more "optional adoption"
Let's examine how functions with default argument values are compiled in Kotlin to see if there's a difference in method count. It may differ depending on the target platform, so we'll look into Kotlin for JVM first.
For the function fun foo(parameter: Any, option: Boolean = false) the following two methods are generated:
First is foo(Ljava/lang/Object;Z)V which is being called when all arguments are specified at a call site.
Second is synthetic bridge foo$default(Ljava/lang/Object;ZILjava/lang/Object;)V. It has 2 additional parameters: Int mask that specifies which parameters were actually passed and an Object parameter which currently is not used, but reserved for allowing super-calls with default arguments in the future.
That bridge is called when some arguments are omitted at a call-site. The bridge analyzes the mask, provides default values for omitted arguments and then calls the first method now specifying all arguments.
When you place #JvmOverloads annotation on a function, additional overloads are generated, one per each argument with default value. All these overloads delegate to foo$default bridge. For the foo function the following additional overload will be generated: foo(Ljava/lang/Object;)V.
Thus, from the method count point of view, in a situation when a function has only one parameter with default value, it's no matter whether you use overloads or default values, you'll get two methods. But if there's more than one optional parameter, using default values instead of overloads will result in less methods generated.
Overloads could be preferred when the implementation of a function gets simpler when parameter is omitted.
Consider the following example:
fun compare(v1: T, v2: T, ignoreCase: Boolean = false) =
if (ignoreCase)
internalCompareWithIgnoreCase(v1, v2)
else
internalCompare(v1, v2)
When it is called like compare(a, b) and ignoreCase is omitted, you actually pay twice for not using ignoreCase: first is when arguments are checked and default values are substituted instead of omitted ones and second is when you check the ignoreCase in the body of compare and branch to internalCompare based on its value.
Adding an overload will get rid of these two checks. Also a method with such simple body is more likely to be inlined by JIT compiler.
fun compare(v1: T, v2: T) = internalCompare(v1, v2)
I was asked the following question:
How would you declare the parameter type in the following cases
— T is a simple type (e.g. int) and is used as an "in" parameter.
— T is a complicated type, and parameter is used as an "in"
parameter.
— T is a simple type and is used as an "out" parameter.
I supposed that in the first case we can simply pass it by value since the performance penalty is not so much, in the second case we should pass it as a reference since it is a more complicated type, and in the third case we should pass it by reference since it is an out parameter. Am I right? Is there any reason to not use reference in all the cases? From the question I can not understand if "in parameter" means that this would not change inside the function so we can pass it as const.
— T is a simple type (e.g. int) and is used as an "in" parameter.
In this case, I'd just pass T (e.g. int) by value.
— T is a complicated type, and parameter is used as an "in" parameter.
In this case, I'd pass T using reference to const: const T& (to avoid e.g. useless and potentially expensive deep-copies).
— T is a simple type and is used as an "out" parameter.
In this case, I'd pass by reference (non-const): T&. This allows modifications done to the parameter value inside the function body to be "visible" outside of the function body, at the call site (think e.g. of a swapping function, that could have a prototype like void swap(T& x, T& y);).
(i'm using Visual C+++ 2010)
suppose i have defined a tuple like this:
typedef std::tr1::tuple<
int //i want to set its default value to 9
, double //i want to set its default value to 3.3
, int //i want to set its default value to 2
, double //i want to set its default value to -7.2
> Mytuple;
i can do that in a struct. but i wonder if it is possible to do that in std::tr1::tuple.
Besides, i want to know when shoud i use std::tr1:tuple or struct?
anyone can help me?
A tuple is not a magical replacement for a struct. Their purposes are very different. A struct is, first and foremost, a language construct. A tuple is a library construct.
Structs get to have default values because the language says that you can write constructors to give them default values. The language then takes responsibility to call that constructor to initialize the struct. tuple, as a library construct, has no such capabilities, anymore than you can give std::vector<T> a default T that it will always automatically use. You can provide initial values for each member, but you can't give it defaults.
And if you think about it, you wouldn't want to. Imagine if someone could say that every tuple<int, float> was always created with 3 and 54.221. Even if some other code created it that knew nothing about this rule, it would have to be followed, (just as constructors for the type are used everywhere that type is used). Remember: every tuple<int, float> is the same type.
Really, a tuple is a substitute for the inability to perform reflection on a struct and do compile-time iteration over its members. The other main reason they exist is to be able to have compile-time dynamic structures (that is, the ability to create aggregates of types based on compile-time arguments, rather than a static list directly written into a file).
So unless you need to use std::tie (for effectively returning multiple values), iteration over members (ie: call some template function for each member of an object), or some similar specialized code, you should be using a struct.
So here's my question in the function declaration there is an argument and it is already initialized to a certain value. What are the procedures to call this function and use that default value, or is it just a way to document code, telling other programmers what you expect them to use as a value for the parameter? Thank you.
enum File
{
XML = 0,
PDF = 1,
};
Char *SetSection(const File = XML);
If I understand your question correctly, simply calling SetSection with no parameters will do.
SetSection();
The above call gets translated (for lack of a better term) to:
SetSection(XML);
It means that the function can be called without parameters in which case the default value, XML, will be used.
In this case, File is a default argument. Calling SetSection() without arguments will set the File argument to the default value specified in the declaration.
If you call
SetSection();
It will call SetSection(XML) instead.
This is why the optional parameters have to be at the end of all parameters. If you don't provide enough parameters, it will use the default.
XML is the standard parameter.
You can call it with SetSection(); (But SetSection(XML) or SetSection(PDF) are valid, too).
What you are seeing in the declaration is a default argument value.
If you call SetSection(); it is the same as calling SetSection(XML);
You can also call SetSelection(PDF); or use any other valid parameter to override the default.
You may also be seeing the result of an incremental development which started with the function having no parameter and calls to the function scattered throughout the code. Then the alternative file type of PDF was introduced, but the prototype was changed to have a default value, which meant not having to change the existing call site.