General programming - calling a non void method but not using value - methods

This is general programming, but if it makes a difference, I'm using objective-c. Suppose there's a method that returns a value, and also performs some actions, but you don't care about the value it returns, only the stuff that it does. Would you just call the method as if it was void? Or place the result in a variable and then delete it or forget about it? State your opinion, what you would do if you had this situation.

A common example of this is printf, which returns an int... but you rarely see this:
int val = printf("Hello World");

Yeah just call the method as if it was void. You probably do it all the time without noticing it. The assignment operator '=' actually returns a value, but it's very rarely used.

It depends on the environment (the language, the tools, the coding standard, ...).
For example in C, it is perfectly possible to call a function without using its value. With some functions like printf, which returns an int, it is done all the time.
Sometimes not using a value will cause a warning, which is undesirable. Assigning the value to a variable and then not using it will just cause another warning about an unused variable. For this case the solution is to cast the result to void by prefixing the call with (void), e.g.
(void) my_function_returning_a_value_i_want_to_ignore().

There are two separate issues here, actually:
Should you care about returned value?
Should you assign it to a variable you're not going to use?
The answer to #2 is a resounding "NO" - unless, of course, you're working with a language where that would be illegal (early Turbo Pascal comes to mind). There's absolutely no point in defining a variable only to throw it away.
First part is not so easy. Generally, there is a reason value is returned - for idempotent functions the result is function's sole purpose; for non-idempotent it usually represents some sort of return code signifying whether operation was completed normally. There are exceptions, of course - like method chaining.

If this is common in .Net (for example), there's probably an issue with the code breaking CQS.
When I call a function that returns a value that I ignore, it's usually because I'm doing it in a test to verify behavior. Here's an example in C#:
[Fact]
public void StatService_should_call_StatValueRepository_for_GetPercentageValues()
{
var statValueRepository = new Mock<IStatValueRepository>();
new StatService(null, statValueRepository.Object).GetValuesOf<PercentageStatValue>();
statValueRepository.Verify(x => x.GetStatValues());
}
I don't really care about the return type, I just want to verify that a method was called on a fake object.

In C it is very common, but there are places where it is ok to do so and other places where it really isn't. Later versions of GCC have a function attribute so that you can get a warning when a function is used without checking the return value:
The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is useful for functions where not checking the result is either a security problem or always a bug, such as realloc.
int fn () __attribute__ ((warn_unused_result));
int foo ()
{
if (fn () < 0) return -1;
fn ();
return 0;
}
results in warning on line 5.
Last time I used this there was no way of turning off the generated warning, which causes problems when you're compiling 3rd-party code you don't want to modify. Also, there is of course no way to check if the user actually does something sensible with the returned value.

Related

C++ return value and move rule exceptions

When we return a value from a C++ function copy-initialisation happens. Eg:
std::string hello() {
std::string x = "Hello world";
return x; // copy-init
}
Assume that RVO is disabled.
As per copy-init rule if x is a non-POD class type, then the copy constructor should be called. However for C++11 onward, I see move-constrtuctor being called. I could not find or understand the rules regarding this https://en.cppreference.com/w/cpp/language/copy_initialization. So my first question is -
What does the C++ standard say about move happening for copy-init when value is returned from function?
As an extension to the above question, I would also like to know in what cases move does not happen. I came up with the following case where copy-constructor is called instead of move:
std::string hello2(std::string& param) {
return param;
}
Finally, in some library code I saw that std::move was being explicitly used when returning (even if RVO or move should happen). Eg:
std::string hello3() {
std::string x = "Hello world";
return std::move(x);
}
What is the advantage and disadvantage of explicitly using std::move when returning?
You are confused by the fact that initialization via the move constructor is a special case of "copy initialization", and does not come as seperate concept. Check the notes on the cppreference page.
If other is an rvalue expression, move constructor will be selected by overload resolution and called during copy-initialization. There is no such term as move-initialization.
For returning a value from the function, check the description of returning on cppreference. It says in a box called "automatic move from local variables and parameters", where expression refers to what you return (warning: that quote is shortened! read the original for full details about other cases):
If expression is a (possibly parenthesized) id-expression that names a variable whose type is [...] a non-volatile object type [...] and that variable is declared [...] in the body or as a parameter of the [...] function, then overload resolution to select the constructor to use for initialization of the returned value is performed twice: first as if expression were an rvalue expression (thus it may select the move constructor), and if the first overload resolution failed [...] then overload resolution is performed as usual, with expression considered as an lvalue (so it may select the copy constructor).
So in the special case of returning a local variable, the variable can be treated as r-value, even if normal syntactic rules would make it a l-value. The spirit of the rule is that after the return, you can't find out whether the value of the local variable has been destroyed during the copy-initialization of the returned value, so moving it does not do any damage.
Regarding your second question: It is considered bad style to use std::move while returning, because moving will happen anyway, and it inhibits NRVO.
Quoting the C++ core guidelines linked above:
Never write return move(local_variable);, because the language already knows the variable is a move candidate. Writing move in this code won’t help, and can actually be detrimental because on some compilers it interferes with RVO (the return value optimization) by creating an additional reference alias to the local variable.
So that library code you quote is suboptimal.
Also, you can not implicitly move from anything that is not local to the function (that is local variables and value parameters), because implicit moving may move from something that is still visible after the function returned. In the quote from cppreference, the important point is "a non-volatile object type". When you return std::string& param, that is a variable with reference type.

Boolean parameters - should I name them?

so i just came across some code that reads like so:
checkCalculationPeriodFrequency("7D", "7D", SHOULD_MATCH);
and
checkCalculationPeriodFrequency("7D", "8D", SHOULD_NOT_MATCH);
Let's not worry about what the code does for now (or indeed, ever), but instead, let's worry about that last parameter - the SHOULD_MATCH and SHOULD_NOT_MATCH
Its something i've thought of before but thought might be "bad" to do (inasmuch as "bad" holds any real meaning in a postmodernist world).
above, those values are declared (as you might have assumed):
private boolean SHOULD_MATCH = true;
private boolean SHOULD_NOT_MATCH = false;
I can't recall reading about "naming" the boolean parameter passed to a method call to ease readability, but it certainly makes sense (for readability, but then, it also hides what the value is, if only a teeny bit). Is this a style thing that others have found is instagram or like, soooo facebook?
Naming the argument would help with readability, especially when the alternative is usually something like
checkCalculationFrequency("7D",
"8D",
true /* should match */);
which is ugly. Having context-specific constants could be a solution to this.
I would actually go a step further and redefine the function prototype to accept an enum instead:
enum MatchType {
ShouldMatch,
ShouldNotMatch
};
void checkCalculationFrequency(string a, string b, MatchType match);
I would prefer this over a boolean, because it gives you flexibility to extend the function to accept other MatchTypes later.
I suggest you not to do this way.
First, for each object, the two members SHOULD_MATCH and SHOULD_NOT_MATCH are regenerated. And that's not good because it's not a behavior of the object. So it you want to use is, at least describe it as STATIC FINAL.
Second, I prefer to use an enum instead, because you can control completely the value of the param, i.e. when you use it, you must use either SHOULD_MATCH or SHOULD_NOT_MATCH, not just true or false. And this increase the readability too.
Regards.
It is indeed for readability. The idea is that the reader of the function call might not know immediately what the value true mean in the function call, but SHOULD_MATCH conveys the meaning immediately (and if you need to look up the actual value, you can do so with not much effort).
This becomes even more understandable if you have more than one boolean parameters in the function call: which true means what?
The next step in this logic is to create named object values (e.g. via enum) for the parameter values: you cannot pass on the wrong value to the function (e.g. in the example of three boolean parameters, nothing stops me from passing in SHOULD_MATCH for all of them, even though it does not make sense semantically for that function).
It's definitely more than a style thing.
We have a similar system that takes takes input from a switch in the form of boolean values, 1 or 0, which is pretty much the same as true or false.
In this system we declare our variables OPEN = true and CLOSED = false* and pass them into functions which perform different actions depending on the state of the switch. Now if someone happens to hook up the switch differently it may be that we now get the value 0 when it is OPEN and 1 when it is CLOSED.
By having named boolean variables we can easily adapt the system without having to change the logic throughout. The code becomes self documenting because developers can clearer see what action is meant to be taken in which case without worrying what value comes.
Of course the true purpose of the boolean value should be well documented else where and it is in our system....honest....
*(maybe we use OPEN, !OPEN I forget)

panic for multilevel returns

Is there a better way to return from long sequences of recursive function calls?
I currently panic with a marker value like this:
type exitNow int
...
panic(exitnow(0))
to return multiple levels at once. At the root function a call to recover does general error handling (turning panics into errors) and handles exitNow as a special case.
This works fine I just want to know if there is a better way.
I already use a bool return value for a related purpose but using another one for this would be a pain. (every call to every function would need an if statment)
If it helps any this is part of the implimentation of a recusive decent parser.
I use this approach myself in my parsers. I don't panic with an integer value though. I use the actual current error as the panic message. The top level call doing the recover() simply appends some file/line/column information and then returns it as a regular error.
This method, and just returning errors from all functions are the only ways to do this in Go. The panic approach is a great deal more effective for the parser case, as it makes the lexer rules considerably simpler to implement (and read) as there are no if err != nil { return } parts littered everywhere.

scala coalesces multiple function call parameters into a Tuple -- can this be disabled?

This is a troublesome violation of type safety in my project, so I'm looking for a way to disable it. It seems that if a function takes an AnyRef (or a java.lang.Object), you can call the function with any combination of parameters, and Scala will coalesce the parameters into a Tuple object and invoke the function.
In my case the function isn't expecting a Tuple, and fails at runtime. I would expect this situation to be caught at compile time.
object WhyTuple {
def main(args: Array[String]): Unit = {
fooIt("foo", "bar")
}
def fooIt(o: AnyRef) {
println(o.toString)
}
}
Output:
(foo,bar)
No implicits or Predef at play here at all -- just good old fashioned compiler magic. You can find it in the type checker. I can't locate it in the spec right now.
If you're motivated enough, you could add a -X option to the compiler prevent this.
Alternatively, you could avoid writing arity-1 methods that accept a supertype of TupleN.
What about something like this:
object Qx2 {
#deprecated def callingWithATupleProducesAWarning(a: Product) = 2
def callingWithATupleProducesAWarning(a: Any) = 3
}
Tuples have the Product trait, so any call to callingWithATupleProducesAWarning that passes a tuple will produce a deprecation warning.
Edit: According to people better informed than me, the following answer is actually wrong: see this answer. Thanks Aaron Novstrup for pointing this out.
This is actually a quirk of the parser, not of the type system or the compiler. Scala allows zero- or one-arg functions to be invoked without parentheses, but not functions with more than one argument. So as Fred Haslam says, what you've written isn't an invocation with two arguments, it's an invocation with one tuple-valued argument. However, if the method did take two arguments, the invocation would be a two-arg invocation. It seems like the meaning of the code affects how it parses (which is a bit suckful).
As for what you can actually do about this, that's tricky. If the method really did require two arguments, this problem would go away (i.e. if someone then mistakenly tried to call it with one argument or with three, they'd get a compile error as you expect). Don't suppose there's some extra parameter you've been putting off adding to that method? :)
The compile is capable of interpreting methods without round brackets. So it takes the round brackets in the fooIt to mean Tuple. Your call is the same as:
fooIt( ("foo","bar") )
That being said, you can cause the method to exclude the call, and retrieve the value if you use some wrapper like Some(AnyRef) or Tuple1(AnyRef).
I think the definition of (x, y) in Predef is responsible. The "-Yno-predefs" compiler flag might be of some use, assuming you're willing to do the work of manually importing any implicits you otherwise need. By that I mean that you'll have to add import scala.Predef._ all over the place.
Could you also add a two-param override, which would prevent the compiler applying the syntactic sugar? By making the types taking suitably obscure you're unlikely to get false positives. E.g:
object WhyTuple {
...
class DummyType
def fooIt(a: DummyType, b: DummyType) {
throw new UnsupportedOperationException("Dummy function - should not be called")
}
}

Using function arguments as local variables

Something like this (yes, this doesn't deal with some edge cases - that's not the point):
int CountDigits(int num) {
int count = 1;
while (num >= 10) {
count++;
num /= 10;
}
return count;
}
What's your opinion about this? That is, using function arguments as local variables.
Both are placed on the stack, and pretty much identical performance wise, I'm wondering about the best-practices aspects of this.
I feel like an idiot when I add an additional and quite redundant line to that function consisting of int numCopy = num, however it does bug me.
What do you think? Should this be avoided?
As a general rule, I wouldn't use a function parameter as a local processing variable, i.e. I treat function parameters as read-only.
In my mind, intuitively understandabie code is paramount for maintainability, and modifying a function parameter to use as a local processing variable tends to run counter to that goal. I have come to expect that a parameter will have the same value in the middle and bottom of a method as it does at the top. Plus, an aptly-named local processing variable may improve understandability.
Still, as #Stewart says, this rule is more or less important depending on the length and complexity of the function. For short simple functions like the one you show, simply using the parameter itself may be easier to understand than introducing a new local variable (very subjective).
Nevertheless, if I were to write something as simple as countDigits(), I'd tend to use a remainingBalance local processing variable in lieu of modifying the num parameter as part of local processing - just seems clearer to me.
Sometimes, I will modify a local parameter at the beginning of a method to normalize the parameter:
void saveName(String name) {
name = (name != null ? name.trim() : "");
...
}
I rationalize that this is okay because:
a. it is easy to see at the top of the method,
b. the parameter maintains its the original conceptual intent, and
c. the parameter is stable for the rest of the method
Then again, half the time, I'm just as apt to use a local variable anyway, just to get a couple of extra finals in there (okay, that's a bad reason, but I like final):
void saveName(final String name) {
final String normalizedName = (name != null ? name.trim() : "");
...
}
If, 99% of the time, the code leaves function parameters unmodified (i.e. mutating parameters are unintuitive or unexpected for this code base) , then, during that other 1% of the time, dropping a quick comment about a mutating parameter at the top of a long/complex function could be a big boon to understandability:
int CountDigits(int num) {
// num is consumed
int count = 1;
while (num >= 10) {
count++;
num /= 10;
}
return count;
}
P.S. :-)
parameters vs arguments
http://en.wikipedia.org/wiki/Parameter_(computer_science)#Parameters_and_arguments
These two terms are sometimes loosely used interchangeably; in particular, "argument" is sometimes used in place of "parameter". Nevertheless, there is a difference. Properly, parameters appear in procedure definitions; arguments appear in procedure calls.
So,
int foo(int bar)
bar is a parameter.
int x = 5
int y = foo(x)
The value of x is the argument for the bar parameter.
It always feels a little funny to me when I do this, but that's not really a good reason to avoid it.
One reason you might potentially want to avoid it is for debugging purposes. Being able to tell the difference between "scratchpad" variables and the input to the function can be very useful when you're halfway through debugging.
I can't say it's something that comes up very often in my experience - and often you can find that it's worth introducing another variable just for the sake of having a different name, but if the code which is otherwise cleanest ends up changing the value of the variable, then so be it.
One situation where this can come up and be entirely reasonable is where you've got some value meaning "use the default" (typically a null reference in a language like Java or C#). In that case I think it's entirely reasonable to modify the value of the parameter to the "real" default value. This is particularly useful in C# 4 where you can have optional parameters, but the default value has to be a constant:
For example:
public static void WriteText(string file, string text, Encoding encoding = null)
{
// Null means "use the default" which we would document to be UTF-8
encoding = encoding ?? Encoding.UTF8;
// Rest of code here
}
About C and C++:
My opinion is that using the parameter as a local variable of the function is fine because it is a local variable already. Why then not use it as such?
I feel silly too when copying the parameter into a new local variable just to have a modifiable variable to work with.
But I think this is pretty much a personal opinion. Do it as you like. If you feel sill copying the parameter just because of this, it indicates your personality doesn't like it and then you shouldn't do it.
If I don't need a copy of the original value, I don't declare a new variable.
IMO I don't think mutating the parameter values is a bad practice in general,
it depends on how you're going to use it in your code.
My team coding standard recommends against this because it can get out of hand. To my mind for a function like the one you show, it doesn't hurt because everyone can see what is going on. The problem is that with time functions get longer, and they get bug fixes in them. As soon as a function is more than one screen full of code, this starts to get confusing which is why our coding standard bans it.
The compiler ought to be able to get rid of the redundant variable quite easily, so it has no efficiency impact. It is probably just between you and your code reviewer whether this is OK or not.
I would generally not change the parameter value within the function. If at some point later in the function you need to refer to the original value, you still have it. in your simple case, there is no problem, but if you add more code later, you may refer to 'num' without realizing it has been changed.
The code needs to be as self sufficient as possible. What I mean by that is you now have a dependency on what is being passed in as part of your algorithm. If another member of your team decides to change this to a pass by reference then you might have big problems.
The best practice is definitely to copy the inbound parameters if you expect them to be immutable.
I typically don't modify function parameters, unless they're pointers, in which case I might alter the value that's pointed to.
I think the best-practices of this varies by language. For example, in Perl you can localize any variable or even part of a variable to a local scope, so that changing it in that scope will not have any affect outside of it:
sub my_function
{
my ($arg1, $arg2) = #_; # get the local variables off the stack
local $arg1; # changing $arg1 here will not be visible outside this scope
$arg1++;
local $arg2->{key1}; # only the key1 portion of the hashref referenced by $arg2 is localized
$arg2->{key1}->{key2} = 'foo'; # this change is not visible outside the function
}
Occasionally I have been bitten by forgetting to localize a data structure that was passed by reference to a function, that I changed inside the function. Conversely, I have also returned a data structure as a function result that was shared among multiple systems and the caller then proceeded to change the data by mistake, affecting these other systems in a difficult-to-trace problem usually called action at a distance. The best thing to do here would be to make a clone of the data before returning it*, or make it read-only**.
* In Perl, see the function dclone() in the built-in Storable module.
** In Perl, see lock_hash() or lock_hash_ref() in the built-in Hash::Util module).

Resources