michuu
michuu

Reputation: 325

Is it safe to use the unary plus operator?

I saw code that goes like this:

double d = GetDouble();
DoSomething(+d);
DoSomething(-d);

I know in it is potentially dangerous and not recommended in C++ to use the unary + just to emphasize that the value is positive. <EDIT>"just to emphasize that the value is positive" was a mental shortcut. I know it doesn't make a negative value positive.</EDIT>

The C# language reference doesn't say much about it:

The unary + operator returns the value of its operand.

There is a question on SO about this, but it is tagged with C, C++ and C#, and none of the answers clearly mentions C#.

Upvotes: 2

Views: 208

Answers (3)

Peter Csala
Peter Csala

Reputation: 22849

+ and - will not change the original double value if that's what you mean by safe.

double d = 7d;
Console.WriteLine(d);  //7
Console.WriteLine(+d); //7
Console.WriteLine(-d); //-7
Console.WriteLine(d);  //7

//OR
d = -7d;
Console.WriteLine(d);  //-7
Console.WriteLine(+d); //-7
Console.WriteLine(-d); //7
Console.WriteLine(d);  //-7

Upvotes: 1

Narish
Narish

Reputation: 760

The other answers have provided a great explanation of what will go on with use of +.

Just wanted to flag that just like in C/C++ there also is the integral numeric types all have unsigned versions. Of course, both share the same concerns of wrapping around when bad operations are done with them

The following code snippet is just a joke, don't kill me, but here is an extension method to check if a numeric type is positive without risk of altering the original's value or typing

public static class NumericExtensions<T> where T : struct
{
    public static bool IsPositive(this T num) =>
        num switch  
        {  
            num is uint _ => true,
            num is int i => i > 0,
            num is ulong _ => true,
            num is long l => l > 0,
            num is double d => d > 0,
            num is float f => f > 0,
            num is decimal m => m > 0m
            //... add remaining numeric types
            _ => false //or throw exception
        };
}

Upvotes: 0

Sweeper
Sweeper

Reputation: 274835

As this answer of the question you linked says, unary + in C(++) does do something, and is not necessarily a no-op. This is true in C# too.

C# only has these unary + operators (See spec):

int operator +(int x);
uint operator +(uint x);
long operator +(long x);
ulong operator +(ulong x);
float operator +(float x);
double operator +(double x);
decimal operator +(decimal x);

So if x is a short, +x would be of type int, because the first operator is selected by overload resolution. As a result, something like this does not compile:

short x = 1;
short y = +x;

This also affects overload resolution, among other things. Just like the code presented in this answer, if you do:

public class C {
    public static void Foo(int x) {
        Console.WriteLine("int");
    }
    
    public static void Foo(short x) {
        Console.WriteLine("short");
    }
}

C.Foo(x) where x is a short will print short, but C.Foo(+x) will print int.

Does this situations like the above happens often enough that makes +x a "bad" or "unsafe" practice? That is for you to decide.

Of course, if x is of a custom struct/class type, then +x could do basically anything. Unary + is overloadable.

Upvotes: 7

Related Questions