469,358 Members | 1,629 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,358 developers. It's quick & easy.

Using ref

Hi,

Form a performance perspective, is it wise to use the ref statement as much
as possible?

Thanks!
Arjen

Jul 2 '08
65 3427
Hilton <no****@nospam.comwrote:
-snip differences between pass by value and pass by reference argument-
OK, back to basics and as simple as I can make it. Let use the C# code:

void Go ()
{
int x = 10;

Method (ref x);
}

void Method (ref int y)
{
y = 20;
}

I am claiming that this is exactly the same as the C code that has "Method
(&x)" (caller) and "Method (int *py)" (callee). All that is happening is
that the compiler is hiding the 'ugliness' from you, so that when you write
"y=20" (above), it really does a "*py= 20".
This is the first time I've ever seen understanding what is happening
on a machine level cause a misunderstanding....

You are ignoring what ELSE you can do in C, but can't in C# -- namely,
you can assign a different address to py.

void Method (int *py) {
int z;
py=&z;
*py = 2;
}

In C# y can never be anything but another way of saying x.

So IMHO, it is just some language/compiler smoke and mirrors, the
*same thing* is happening under the covers.
All languages and compilers are just smoke and mirrors over the
hardware. But it's important smoke and mirrors.

--
J.B. Moreno
Jul 5 '08 #51
raylopez99 <ra********@yahoo.comwrote:
So are you saying 'pass-by-value' is like 'constant' in C++ (which to
my newbie knowledge C# lacks) in that you can safely pass an object
to a function so it cannot be manipulated to change the original? If
so, please let me know how to do that, since honestly once I learned
C# I have yet to find how you can make a function/method take a 'read
only' copy of a class (not a primitive type, but of a class). In
fact, Googling this confirmed this fact (see below). So I don't see
how pass-by-value is any 'safer' (or read-only) than 'pass-by-value'
for a class passed.
-snip
Furthermore, const can only be applied to intrinsic types.
Intrinsic = value-type variables, i.e. not classes.

Go read Jon's article on
parameters....<http://www.yoda.arachsys.com/csharp/parameters.html>.

--
J.B. Moreno
Jul 5 '08 #52
Pavel Minaev <in****@gmail.comwrote:
It is really unfortunate that C# designers chose to overload the term
"reference" for both object references and byref arguments
Not really. It means pointer in both cases. Object variables are
pointers/references to objects, byref arguments are when a
pointer/references to the argument is passed instead of the value of
the argument..

--
J.B. Moreno
Jul 5 '08 #53
J.B. Moreno <pl***@newsreaders.comwrote:
Furthermore, const can only be applied to intrinsic types.

Intrinsic = value-type variables, i.e. not classes.
Not quite - const can be applied to string (which is a reference type)
but not DateTime (which is a value type).

In fact, you can use any reference type for a constant field - but for
anything other than string, the only allowed value is null :) Basically
it's a case of whether or not the value itself counts as a constant in
C# terms.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Jul 5 '08 #54
On Jul 5, 1:40*pm, "J.B. Moreno" <pl...@newsreaders.comwrote:
Pavel Minaev <int...@gmail.comwrote:
It is really unfortunate that C# designers chose to overload the term
"reference" for both object references and byref arguments

Not really. *It means pointer in both cases. *Object variables are
pointers/references to objects, byref arguments are when a
pointer/references to the argument is passed instead of the value of
the argument..
There is a multitude of difference between CLI object references and
CLI managed pointers, regarding which I can only refer you to the CLI
spec. As long as we do not go down to the native code level, they are
different concepts in CLI, and that's what should matters for anything
built on top of that, such as C#; and indeed, it does - semantics of
"ref" and object references in C# are very different.

On a side note, managed pointers do not have to be used strictly for
argument passing - they can also be local variables (which is also
exposed in C++/CLI, though the fact that you can change a value of a
managed pointer variable itself - rather than whatever it points to -
is not), and even return values of methods, though the latter case is
unverifiable per ISO/ECMA spec, and verifiable in .NET only for some
very specific use cases.
Jul 5 '08 #55
Jon Skeet [C# MVP] <sk***@pobox.comwrote:
J.B. Moreno <pl***@newsreaders.comwrote:
Furthermore, const can only be applied to intrinsic types.
Intrinsic = value-type variables, i.e. not classes.

Not quite - const can be applied to string (which is a reference type)
but not DateTime (which is a value type).

In fact, you can use any reference type for a constant field - but for
anything other than string, the only allowed value is null :) Basically
it's a case of whether or not the value itself counts as a constant in
C# terms.
Guess I snipped too much...

The "Furthermore, const can only be applied to intrinsic types" was (I
believe) a statement about C++ that raylopez99 found by Googling. I
was trying to do a cross-language comparison.

--
J.B. Moreno
Jul 5 '08 #56
J.B. Moreno <pl***@newsreaders.comwrote:
In fact, you can use any reference type for a constant field - but for
anything other than string, the only allowed value is null :) Basically
it's a case of whether or not the value itself counts as a constant in
C# terms.

Guess I snipped too much...

The "Furthermore, const can only be applied to intrinsic types" was (I
believe) a statement about C++ that raylopez99 found by Googling.
Not sure - it comes directly after a statement about C#, but it's not
very clear. Ah well...
I was trying to do a cross-language comparison.
Right.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Jul 5 '08 #57
J.B. Moreno <pl***@newsreaders.comwrote:
Hilton <no****@nospam.comwrote:

-snip differences between pass by value and pass by reference argument-
OK, back to basics and as simple as I can make it. Let use the C# code:
-snip-
void Method (ref int y)
{
y = 20;
}

I am claiming that this is exactly the same as the C code that has "Method
(&x)" (caller) and "Method (int *py)" (callee). All that is happening is
that the compiler is hiding the 'ugliness' from you, so that when you write
"y=20" (above), it really does a "*py= 20".

This is the first time I've ever seen understanding what is happening
on a machine level cause a misunderstanding....

You are ignoring what ELSE you can do in C, but can't in C# -- namely,
you can assign a different address to py.
-snip-
In C# y can never be anything but another way of saying x.
Which is to say that the reference arguments/parameters are language
constructs -- it tells the compiler to behave in a certain way.

C# tries to make this unmistakable by requiring the keyword ref on both
the argument and the parameter (unlike in other languages where the
keyword is only used on the parameter).

It tells the compiler that instead of passing the value of the argument
itself, to instead pass a pointer to the argument and that inside the
function being called, the pointer to the argument isn't to be changed
and is to be automatically dereferenced whenever used.

You can call this "smoke and mirrors" if you like and say that it's all
the same underneath, but this ignores the fact that this type of smoke
and mirrors is exactly what a high level language like C or C# is -- a
way of "hiding" the underlying instructions from programmer.

--
J.B. Moreno
Jul 5 '08 #58
Hilton wrote:
Peter Duniho wrote:
>Hilton wrote:
What example is it that you are saying uses "ldloca.s"? Are you
comparing this to managed code? If not, how can that be "same as C"? In
any case, the "ldloca.s" instruction is used when you pass by
reference, yes. But that's only when you use the "ref" or "out"
keyword.

My point is that the C# call "method (ref x)" is defined by
you/Jon/community as being pass by reference, yet the C call "method
(&x)" is defined by you/Jon/community as being pass by value -
they're doing EXACTLY the same thing. Both simply take the address
That's true. They both use one level of indirection.
of x and pass it along. Does a prettier syntax changes the entire
concept? And if Microsoft has used "&" instead of "ref" in its
Apparently, according to the definition Jon is quoting from,
pass-by-reference is all about the syntax. So stop using those words (he's
undoubtedly using the official definition accepted in computer science) and
simply speak of "levels of indirection".
definition of the C# language, would that now mean that the C# call
"method (&x)" was now pass by value???

Pete, really, I don't want to spend more of your time or my time on
this. In my mind (which I agree probably doesn't fit the pure
definition of the pass-by definitions), if I pass a reference or
pointer to my chunk of data, I'm passing by reference (the focus
being on the data, not the actual parameter). I think millions of
other people think that way too since pass-by-reference has been
taught for decades when discussing C, but apparently that capability
never existed.
Hilton

Jul 8 '08 #59
Peter Duniho wrote:
On Thu, 03 Jul 2008 13:19:29 -0700, Hilton <no****@nospam.comwrote:
>[...]
So, if I understand you correctly, the determination of "pass by
value" or
"pass by reference" is based on syntax and not functionality (here I
mean what actually gets passed etc).

It's based on what the language itself supports.

You can write C code that has the same effect as lambda expressions in
C#. That doesn't mean C supports lambda expressions.
>[...]
Jon, is this C# code "pass by value" or "pass by reference"?

The C# code is clearly "by reference".
>By your earlier claims, the C code is "pass by value".

Yes. Since C doesn't support "by reference", it would have to be.
>So either:

1. The C# is "pass by value" in which case "ref" does not mean
"pass by reference", or

Nope.
>2. The C# code is "pass by reference" even though exactly the same
as its C
counterpart, just a different syntax, or

It's not "exactly the same". There are important differences between
the two that you are ignoring.
"Pass by reference" is exactly syntactic sugar for adding a level of
indirection (i.e. take the address, pass the pointer).

C# has the pointer syntax as well, and just as in C++, the pointer syntax is
more powerful than the reference syntax.
>
>3. The whole "pass by value/reference" claim is a syntactic claim
and not a
functional/performance claim.
It affects the CLR security system as well. When the parameter is defined
as pass-by-reference, the verifier checks that no pointer arithmetic is
performed, the reference isn't rebound, etc. This is what lets
pass-by-reference be used in partial trust scenarios even where the
functionally identical pointer passing is disallowed (the verifier isn't
smart enough to distinguish dangerous operations that break type safety --
pointer arithmetic -- from perfectly safe usage of pointers).
>
It is a critically important description of how the _language_ works.
Just because you can get the compiled result to accomplish the same
thing, that doesn't mean that the _language_ concepts are the same.

Pete

Jul 8 '08 #60
J.B. Moreno wrote:
Hilton <no****@nospam.comwrote:
-snip differences between pass by value and pass by reference
argument-
>OK, back to basics and as simple as I can make it. Let use the C#
code:

void Go ()
{
int x = 10;

Method (ref x);
}

void Method (ref int y)
{
y = 20;
}

I am claiming that this is exactly the same as the C code that has
"Method (&x)" (caller) and "Method (int *py)" (callee). All that is
happening is that the compiler is hiding the 'ugliness' from you, so
that when you write "y=20" (above), it really does a "*py= 20".

This is the first time I've ever seen understanding what is happening
on a machine level cause a misunderstanding....

You are ignoring what ELSE you can do in C, but can't in C# -- namely,
you can assign a different address to py.
so is this "pass-by-reference"?

void Func(int * const py);

Of course not, although py is now permanently set to the original actual
parameter. You can still do things like (py - arrayBase) which a C#
pass-by-reference doesn't permit. But a C++ pass-by-reference does...

void Func2(int& ry);

You can most certainly say (&ry - arrayBase) to get the exact same effect.
In C++, the reference syntax is no more and no less than syntactic sugar.
In C#, the reference syntax is much more. Calling these both by the same
name is more confusing than calling the C code pass-by-reference. There are
two "real concepts" going on:

number of levels of indirection
type-safety
>
void Method (int *py) {
int z;
py=&z;
*py = 2;
}

In C# y can never be anything but another way of saying x.

>So IMHO, it is just some language/compiler smoke and mirrors, the
*same thing* is happening under the covers.

All languages and compilers are just smoke and mirrors over the
hardware. But it's important smoke and mirrors.

Jul 8 '08 #61
You remind me of the people who continue to cling to the idea that
Iraq had something to do with the 9/11 attacks and that Hussein was
hiding weapons of mass destruction somewhere in his country, in spite
of absolutely no evidence in support of those ideas and in spite of
volumes of evidence to the contrary.

In other words, you've decided on your dogma and no amount of actual
facts will have any effect on your beliefs.
Unfortunately for you, Peter, here you paint yourself as the dogma, not
facts, type.

Plenty of "dual-use" explosives and biological agents were found in Iraq.
That they were found in bunkers with military gas masks nearby suggests that
they were in fact part of a WMD program. Not to mention the documented
instances of Hussein actually using WMD on large segments of his population.

Which is why we ought to restrict this group to programming.
Jul 8 '08 #62
The "Furthermore, const can only be applied to intrinsic types" was (I
believe) a statement about C++ that raylopez99 found by Googling. I
was trying to do a cross-language comparison.
Certainly not true. C++ 'const' can be applied to any variable of any type,
the type pointed to be any pointer or reference, and so on.

C++ 'const' is more like (but much more useful than) C# 'readonly'.
C++0x introduces 'constexpr' which is similar to (but again much more
powerful than) C# 'const'.
Jul 8 '08 #63
>and I barely
>figured out the difference between ref and non-ref (pass by value)
just recently. This thread was good as a refresher. ANd see my
other thread why C# is flawed because you cannot pass an object
using, as in C++, a 'const' keyword to prevent it from being
modified.

It doesn't prevent something from being modified in C++ either.
It does, unless the callee goes out of its way to break its contract (i.e.
uses the const_cast keyword to remove the const). There's no way to turn a
pointer-to-const into a pointer-to-non-const without either a cast or a
union or some really hairy pointer arithmetic, all of which are known to
break type-safety.
>
More importantly, a much better way to ensure that a data structure
isn't modified is simply to make that data structure immutable. For
example, the String class is essentially "const" all the time. Works
great.
Not in C++ it isn't. No matter how immutable you make your object, C++ can
still overwrite the innards if you explicitly work to do so.
>
The lack of "const" for methods or their parameters doesn't make C#
any more flawed than any of the other languages people use on a daily
basis. It just makes it different from one of them.

If having "const" methods and parameters was such an important
feature, everyone would use C++ and no one would use C#, Java, VB,
etc. Odd, then, that so many people find languages other than C++
preferable, or at the very least, just as useful.
Or maybe it is something they really want, but they want garbage collection
and reflection more.

Or, more likely, all the Microsoft C# training never even mentions the
advantages of const-correctness, so they don't even know what they are
missing.
Jul 8 '08 #64
On Tue, 08 Jul 2008 07:42:10 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
>It doesn't prevent something from being modified in C++ either.

It does, unless the callee goes out of its way to break its contract
(i.e.
uses the const_cast keyword to remove the const).
What does it matter _what_ the exception is? The fact is, the exception
exists. As long as the exception exists, it's trivial for someone to
modify something declared as "const" in this context.
>More importantly, a much better way to ensure that a data structure
isn't modified is simply to make that data structure immutable. For
example, the String class is essentially "const" all the time. Works
great.

Not in C++ it isn't. No matter how immutable you make your object,
C++ can
still overwrite the innards if you explicitly work to do so.
This isn't a C++ newsgroup. And presumably the OP would just use "const"
if they were using C++. So forgive me for not going out of my way to
qualify my statements explicitly so that everyone reading them knew they
applied to C#, not C++. It never occurred to me that someone would be
confused.
>The lack of "const" for methods or their parameters doesn't make C#
any more flawed than any of the other languages people use on a daily
basis. It just makes it different from one of them.

If having "const" methods and parameters was such an important
feature, everyone would use C++ and no one would use C#, Java, VB,
etc. Odd, then, that so many people find languages other than C++
preferable, or at the very least, just as useful.

Or maybe it is something they really want, but they want garbage
collection
and reflection more.
Like I said, "==>IF<== having 'const' methods and parameters ==>WAS SUCH
AN IMPORTANT FEATURE<==...".

The question isn't whether people find it useful at all. It's whether
it's important enough for someone to described a language without the
feature as "deeply flawed".

It's just stupid to state or imply that "const" is a critical language
feature. It obviously isn't, however useful it might be to some people.

Pete
Jul 8 '08 #65
On Tue, 08 Jul 2008 07:15:59 -0700, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
Unfortunately for you, Peter, here you paint yourself as the dogma, not
facts, type.
Hardly.
Plenty of "dual-use" explosives and biological agents were found in Iraq.
That they were found in bunkers with military gas masks nearby suggests
that
they were in fact part of a WMD program. Not to mention the documented
instances of Hussein actually using WMD on large segments of his
population.
All completely irrelevant to the claims that had been made regarding an
"imminent threat". Statements like yours are useful for people who want
to engage in diversionary tactics, but not so much when it comes down to
the actual facts.
Which is why we ought to restrict this group to programming.
Yes, you really should have stuck to that advice.
Jul 8 '08 #66

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Enos Meroka | last post: by
3 posts views Thread by Mike L | last post: by
3 posts views Thread by xzzy | last post: by
14 posts views Thread by pmud | last post: by
8 posts views Thread by acb | last post: by
reply views Thread by Metal2You | last post: by
reply views Thread by Eugene Anthony | last post: by
6 posts views Thread by =?Utf-8?B?U2hhd24gU2VzbmE=?= | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.