Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#7 'in' parameters allowed with operator overloading

The recent additions to C# 7 are great and now in the latest release we can pass ValueType (struct) instances to functions by-reference ('by-ref') more efficiently by using the new in keyword.

Using either in or ref in the method declaration means that you avoid the extra 'memory-blt' copy of the entire struct which is normally required in order to preserve by-value semantics. With in, you get this benefit (passing a pointer to the source ValueType itself), but unlike ref, the callee won't be allowed to modify that target (enforcement by the compiler).

In addition to improving the rigor of design intent, in has an added benefit over ref that the call-site syntax is more relaxed than with ref. In fact, you don't need to mention the in keyword at the call-site; it's optional.

Anyway, I noticed that apparently you can define C# operator overloads using in-attributed arguments.

public static bool operator ==(in FILE_ID_INFO x, in FILE_ID_INFO y) => eq(in x, in y);
//       works:            -----^            -----^

This is great if the by-ref semantics actually do prevail in the runtime behavior. But I would find that surprising, because even though C# lets you omit the in keyword in method calls, the generated code at the call site does need to be different. Namely, it needs to emit (e.g.) OpCodes.Ldflda instead of OpCodes.Ldfld, and so forth.

And then there's also the fact that operator overloads don't have a traditional method "call site" that could be decorated with the (albeit, optional) in keyword:

var fid1 = default(FILE_ID_INFO);
var fid2 = default(FILE_ID_INFO);

bool q =    fid1 ==    fid2;
//       ^--- in? ---^      

So, does anyone know if the compiler, JIT, and runtime will honor what the code seems to be allowed to express, such that calls to operator overloads with in-parameters will actually obtain by-ref semantics? I couldn't find any mention of the situation in the docs. Since the code shown above basically continues to work as it did without the in markings, I suppose the alternative would be that the in keyword is just silently ignored here?

like image 492
Glenn Slayden Avatar asked Feb 01 '18 19:02

Glenn Slayden


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

How old is the letter C?

The letter c was applied by French orthographists in the 12th century to represent the sound ts in English, and this sound developed into the simpler sibilant s.


1 Answers

Short answer: The compiler does the right thing. Trust the compiler.

Long answer:

An overloaded operator is simply a syntactic sugar for a static method. An invocation of an overloaded operator is simply a syntactic sugar for an invocation of that method.

That is,

public static bool operator ==(S s1, S s2) { ... }

is just a syntactic sugar for something like

public static bool op_Equality(S s1, S s2) { ... }

and

if (s1 == s2)

is just a syntactic sugar for

if (S.op_Equality(s1, s2))

So whatever behaviour holds for in annotations on normal static methods and normal static method calls also holds for static methods which are operators, and static method invocations which are expressions that use those operators.

like image 94
Eric Lippert Avatar answered Oct 12 '22 13:10

Eric Lippert