16

What are the similarties/differences between a C++ reference and a C# reference ?

Edit:

I'm talking about Object references,as I'm a newbie I was unaware that such a simple line would cause ambiguity,as I have read. Whenever the term "reference" is used,its in context to Object reference,otherwise its explicitly quoted as "managed references".

I think all the people who have answered this question have got what I was trying to say and I made a comment that states clearly what I wanted to ask. I don't see any reason for a downvote,come on guys.

This question does not deserve to be closed.As newbies like me can learn from the insight a lot of experienced people have provided.

Pavitar
  • 4,282
  • 10
  • 50
  • 82
  • 8
    I think this is a real question, but I expect a duplicate to exist somewhere. So I don't agree with your close reason. – CodesInChaos May 07 '11 at 08:11
  • Just a note: there are *object references* and there are *managed references* (aka managed pointers). I thought you were referring to the latter, but apparently I was wrong... just be aware that there's a difference, though. – user541686 May 07 '11 at 08:34
  • @Mehrdad: But everyone (including the official docs) just uses "reference" where you say "object reference". The misunderstanding is yours. – H H May 07 '11 at 08:41
  • 1
    @Henk: *Obviously* I misunderstood, I'm not denying that at all. Just mentioning that both of them exist so that the OP's aware of them, if he's not already. – user541686 May 07 '11 at 08:45
  • 2
    @Mehrdad -- As Jon Skeet pointed out,I was talking about object references.. But your answer is helpful too because I'm a newbie,and it helps to get introduced to more concepts.Always an advantage :) So +1 for your answer. – Pavitar May 07 '11 at 10:01

4 Answers4

13

C# references are closer to C++ pointers than to C++ references.

C# references can be null and have assignment semantics similar to pointers. The difference is that they are black boxes(you can't convert them to integral types) and you can't do arithmetic on them. They also can only point to reference types.

C++ references are quite different(apart from being compiled to pointers too). They are closer to .net managed references which are used for ref parameters. But even then the assignment semantics differ.


Initialization of a reference is something quite different from assignment to it. Despite appear- ances, no operator operates on a reference.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • Disagree; C++ references can also be null, and C# references get assigned just like C++ references. Would you mind providing an example of how they're different? – user541686 May 07 '11 at 08:11
  • 4
    I thought you can only initialize C++ references once, and then all assignments change only the value they point at. And I'm pretty sure that the TC++PL stated they can't be null somewhere. You probably can make them null by casting from a dereferenced null pointer, but I except that to be undefined behavior. – CodesInChaos May 07 '11 at 08:13
  • @mehrdad: in C++ references are initialized, not assigned. And they're not allowed to be null. – H H May 07 '11 at 08:13
  • @Henk: `int &r = *(int*)NULL;` – user541686 May 07 '11 at 08:15
  • 3
    @Mehrdad And can you quote something that says this is defined behavior? You're dereferencing a null pointer after all. – CodesInChaos May 07 '11 at 08:16
  • @CodeInChaos: As far as I know, no dereferencing actually happens here (why should it?), although I admit I haven't read the standard carefully enough to know exactly what it says here. – user541686 May 07 '11 at 08:18
  • 1
    It is undefined, so you can't say whether anything is being dereferenced here. – BoltClock May 07 '11 at 08:22
  • @Mehrdad, I'm not convinced *NULL is even valid C++ – H H May 07 '11 at 08:22
  • @BoltClock: Turns out we're talking about entirely different things; like @Jon Skeet pointed out, I was talking about a managed reference, not an object reference. I'll take off my downvote. – user541686 May 07 '11 at 08:23
  • @Mehrdad: A "managed reference" is not a C# language concept. It may be in C++/CLI though. – H H May 07 '11 at 08:28
  • A managed reference is a CLR concept, not a C# language concept. While they are used internally in `ref`/`out` parameters that's just an implementation detail. As far as the C# language is concerned they don't exist. – CodesInChaos May 07 '11 at 08:30
  • @CodeInChaos, @Henk: Yes, sorry, that's just what I thought of when the question was asked, because I thought of parameter passing and not objects, so I thought that's what the OP meant. It seemed more logical to try to draw a parallel between `int&` and `ref int` than it did to draw one between `int` and `object`... – user541686 May 07 '11 at 08:31
  • Perhaps you should state in the beginning of your post that you're talking about managed references and not variables which have a reference type. – CodesInChaos May 07 '11 at 08:33
  • 5
    There's no such thing as a null reference in C++. An attempt to create one yields undefined behavior. And @CodeInChaos' description of C++ references is correct. (Except that they're not always compiled down to pointers. Conceptually they are nothing more or less than an alias for an object, and often, that is all they're compiled to: modifying a reference will generate code that modifies the object itself, without any additional pointer dereferencing. In complex cases, the compiler *might* fall back to implementing a reference as a pointer, but it shouldn't be mentioned as the default case – jalf May 07 '11 at 08:33
5

The are not very much alike.

The only thing in C# that looks like a C++ reference are parameters with the ref keyword. There are no equivalents of reference variables or fields.

C# reference are in most respects much more like C++ pointers. They can be null etc.

Edit

In C# the term "a reference" always means an object-reference. De-referencing is automatic, that can make comparing with C++ a little difficult:

string h = "hello";
int len = h.Length;   // dereference, Length is a property of the instance
h = null;             // no de-referencing, h itself becomes null.
H H
  • 263,252
  • 30
  • 330
  • 514
  • Disagree; C++ references can also be null, and C# references get assigned just like C++ references; there's no indirection like with C++ pointers. -1 Would you mind providing an example of how they're different? – user541686 May 07 '11 at 08:15
  • 1
    @Mehrdad: It sounds like you're thinking about `ref` parameters in C#, rather than simple references (e.g. the value of a variable of type `string`). Very different things. – Jon Skeet May 07 '11 at 08:19
  • 4
    @Mehrdad You can't reassign a C++ reference, and a C++ reference cannot be NULL. All of those are true of _pointers;_ did you confuse them? – Andres Jaan Tack May 07 '11 at 08:20
  • @Jon: Yes indeed, I was referring to managed references, represented by `ref`, *not* object references... was that not the question being asked? – user541686 May 07 '11 at 08:21
  • @Mehrdad: The most common use of the word "reference" as a noun in C# is the use which is like a C++ pointer, so that's how I interpreted the question. Do you have any reason for thinking the OP was talking about `ref`? – Jon Skeet May 07 '11 at 08:24
  • @Jon: It honestly just didn't pop into my head that the OP meant objects and not parameter passing. :\ `ref` seemed to draw a better parallel with `&` than object references did. – user541686 May 07 '11 at 08:29
1

Update:

Apparently I'd misunderstood the question: I'd understood the word "reference" to be referring to "managed references", not "object references". "Managed references" (preferably called "managed pointers", which I did not do originally) are the feature that allows something like ref int in C#, and are very similar to C++ references. They are a .NET Framework concept, however -- not a C# concept. By constrast, an "object reference" (or just a "reference") is simply referring to a reference type.

In my answer below, I'm referring to managed references/pointers, not objects.


In the implementation, they're almost exactly the same thing: just fancy pointers that aren't supposed to be null.

In the code, they're somewhat different: for one thing, you can't have a "reference variable" in C#, but you can in C++.

i.e., you can say

int x = 5;
int& y = x;

in C++, but you can't say:

int x = 5;
ref int y = x;

in C#.

But the usual assignment semantics apply: Assigning to a reference assigns to the target; there's no way to change the reference itself in C# or C++.


However, it's technically not entirely disallowed entirely by the .NET framework to have a "reference to an int"; in fact, such a type does exist. But no .NET language (other than pure IL) has the ability to declare a variable to have the type of a managed reference, as far as I know.

user541686
  • 205,094
  • 128
  • 528
  • 886
  • 1
    In what way is a C# reference not meant to be null? – Jon Skeet May 07 '11 at 08:15
  • @Jon: I mean like, in my example, if I said `y = 5;` I would not expect it to throw a null reference exception, even though it technically can. – user541686 May 07 '11 at 08:16
  • @Mehrdad: But in your first statement, you claim that C++ references are like C# references, including that they're not meant to be null. That's simply not the case - indeed, it's one of the *differences* between C# references and C++ references. – Jon Skeet May 07 '11 at 08:18
  • @Jon: Do you expect a reference in C++ to be null when you assign to it? (i.e. *should* `int &z = ...; z = 5;` throw a null pointer exception? It's possible in both languages for both of these to happen, but is it expected?) – user541686 May 07 '11 at 08:19
  • @Mehrdad: I don't know enough C++ to be confident in that area, but I'm darned sure I can assign a null value to a string variable in C# for example, which is then a null reference. As per my other comment, it sounds like you're really thinking about `ref` in C# rather than the normal meaning of the noun "reference". – Jon Skeet May 07 '11 at 08:21
  • It doesn't matter if it's null before in C#. Since an assignment to a reference type variable will overwrite the old value without even looking at it. – CodesInChaos May 07 '11 at 08:21
  • @Mehrdad: `string s = null;` is valid C# and `s` is a C# reference. – H H May 07 '11 at 08:24
  • @Jon, @Henk: Yeah, I was thinking of managed references (the type `&`), not object references. We were talking about entirely different things apparently. :\ – user541686 May 07 '11 at 08:24
  • 1
    @Henk: Nah, `s` is a variable. The *value* of `s` is a C# reference ;) – Jon Skeet May 07 '11 at 08:25
  • @Jon: good you end that with a (sort of) smiley. – H H May 07 '11 at 08:35
  • @mehrdad: I leave my downvote. You'd have to introduce "managed reference" and use it consistently to clear this answer up. – H H May 07 '11 at 08:40
  • @Henk: Not sure how exactly you mean I should introduce it... which word is being inconsistent? – user541686 May 07 '11 at 08:41
  • See my comment to the question. – H H May 07 '11 at 08:43
  • @Henk: Saw it, but I still don't know which words exactly you think I should replace...? – user541686 May 07 '11 at 08:45
  • "there's no way to change the reference itself in C#" – H H May 07 '11 at 08:51
  • @Henk: Oh so you mean I should say "change the managed reference variable"? Sounds reasonable but a bit awkward though.. – user541686 May 07 '11 at 08:53
  • And explain/define "managed reference" – H H May 07 '11 at 09:04
  • @Henk: Done; hope that clarifies things. – user541686 May 07 '11 at 09:09
  • With respect to your last paragraph, not just MSIL. C++/CLI also supports tracking references. – Ben Voigt May 08 '11 at 06:38
  • @Ben: Indeed, I paused on that for a second but totally forgot about the `%` type, thanks. – user541686 May 08 '11 at 06:53
1

The question seem stated unprecisely. After reading all the answers and comments I am still not sure if any of them really clarified things.

One of the major simplifications of C# (or the CLR type system) over native C++ is the clear separation into value and reference types with the possibility to pass both either by value or by reference.

Somewhat simplified, C++ on the other hand, only knows "value types" where the application has to decide whether their lifetime is managed automatically or manually. In C++ the term "reference type" denotes a new type declared by writing T& where T is a valid type name. In C++ a reference is a subtle thing: The declaration T& defines an "l-value reference to T" while T&& defines "r-value reference to T" (reference to a temporary object, new concept introduced by c++0x) both beeing different types. The mutual binding rules (if passed as an argument, returned from a function, or used as an l-value or r-value in an assignment expression) of

  • T
  • T const &
  • T const &&
  • T&
  • T&&

are a nightmare although they open possibilities for some very useful and powerful paradigms. Of course, since T* (a pointer type) can be substituted for T in T& or any of it's alternatives you can define a "reference to a pointer-type" type with all the combinations described above. The opposite, however, is not possible, a "pointer to a reference type" is not allowed.

Huh, I hope I confused everything even more...

Cheers,

Paul

Paul Michalik
  • 4,331
  • 16
  • 18