Question

I've been bitten a couple of times by statements in VB.NET (not sure if this effect exists in C#) that appear to be self-referencing, but when they're executed, they don't actually do anything because they require a target and one isn't provided. For example:

Dim MyString as string = "String to test"

' Neither of these lines do anything '
MyString.Replace(" ", "-")
MyString.Substring(0,5)

' This will return the original string, because neither statement did anything '
Messagebox.Show(MyString)

In both cases, it doesn't seem to bother .NET that the statement needs a target to assign the result to, and I don't give it one. Is there a reason that the IDE/compiler doesn't warn me of this effect, or that an exception "StatementDoesntDoAnything" isn't thrown? Since the code is formed in such a way that it will never change anything, it's clearly mis-typed.

Was it helpful?

Solution

It can be hard to tell that ignoring the return value isn't intended, as some functions do some side-effect and return a value.

Functions which "merely" return values would have to be marked as such to have the compiler check them, and that just hasn't been a priority or judged to have enough return on investment (obviously, otherwise they'd have done it :).

OTHER TIPS

Yes, it would be great if methods which have no side-effects could be marked with some kind of [NoSideEffectsAttribute()] so that tools like compilers can warn you, but at present no such thing is known to me.

But you could try FxCop, it can spot lots of subtle programming errors on .NET assemblies.

There are many instances where methods return values that are optionally handled by the programmer. There is no way for the compiler to know that this particular method does nothing. It might have a side effect and the fact that you choose to do nothing with the return value of the method has to be a concious decision on your part.

If the compiler choose to warn you of every instance that this happened then you will get too many false warnings.

It is often difficult for the compiler to determine if the functions "do something". Unless the compiler does rigorous Inter-Procedural Analysis (IPA), it can not determine if the function call has a side effect.

IPA is a slow process that significantly increases the compilers memory requirements so by default most compilers do not perform this.

This is inherited behavior from C, C++, and was orioginally done so that you can choose whether or not to use the return value from a function/method... When you write a function/method that does a bunch of stuff and then returns some value, when you call it, you have the option of writing

variableName = functionName([parameterlist]);  

if you want to use the returnb value in something, or just

functionName([parameterlist]);  

if you don't.

For function methods that have no side effects (like the ones you mention) as you noted, this doesn't quite make sense, but changing it for new languages would run counter to the long history of many many other languages that conform to this standard...

I'm not sure having yet another keyword for forcing or not the return value to be put into a variable would be a good idea for various reason

1 ) Suppose you add a keyword when the return value is optinal (hence implying it is usually mandatory) would cause lots of code to stop compiling or issued tons of warning

2) Suppose you do the reverse, adding a keyword when the return value is forced, some people would simply use dummy variables to store them and keep using it the way ther used to.

3) I don't think lots of people would actually take the time to ponder whether or not the return value is optional or not. In some case, I got to admit it's given, but not always.

Consider the method Dictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value): it checks if the key is in the dictionary, and if it is, it puts the value into the out parameter. The return value is a bool indicating whether the operation was successful. Sometimes you care; sometimes you don't. I think this is a pretty accepted approach for methods like this; if the compiler forced you to assign the return value to a variable, people would have a lot of code like this:

int someValue = 0;
bool discard = IntDictionary.TryGetValue("key", out someValue);

// I don't even care if discard is true or false;
// someValue will be 0 if it wasn't in IntDictionary

I've been bitten a couple of times by

jumping to conclusions, not by

statements in VB.NET ... that ... don't actually do anything

but that are actually very well documented.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top