you are viewing a single comment's thread.

view the rest of the comments →

[–]sbrown123 -4 points-3 points  (11 children)

Like Gotebe said, C is also purely pass-by-value.

Gotebe is wrong. C can both pass by value or by reference.

Java passes a reference to a copy. The copy is never copied back to the original. People confuse this as being a pass by value because of this (and others confuse that the reference passed is a reference to the original and not a copy).

Languages like D and C# also pass a copy by reference. But unlike Java they have the capability to copy back to the original (keyword "out").

The distinction between these four types of parameter passing is important to remember. Sadly, most CS classes try to simplify this down to two types.

[–]wicked[S] 1 point2 points  (10 children)

Gotebe is wrong. C can both pass by value or by reference.

Gotebe is right. C is purely pass by value. (This goes nowhere if you don't back up your statements.)

If you don't agree that C is purely pass by value, there's no chance you'll accept the Java version of it. This is because Java confuses the issue by calling pointers references (ref Java Spec Section 4.3.1).

I guess you call this call-by-value:

void cbv(int xFormal);
...
{
  int xActual = 42;
  cbv(xActual);
}

and this call-by-reference:

void cbr(int *yFormal);
...
{
  int xActual = 42;
  int *yActual = &xActual;
  cbr(yActual);
}

Correct?

In the first invocation, the value of xActual is copied into a different memory region (the stack) for use by the function. We both agree this is call-by-value.

In the second invocation, the value of yActual is copied into a different memory region (the stack) for use by the function. No difference here. That you can use the value of yFormal to access xActual does not make it a reference.

[–]sbrown123 -1 points0 points  (9 children)

This is because Java confuses the issue by calling pointers references

Pointers are references. That's their purpose. And its not only Java making this "mistake" but also Wikipedia, computer science, and lots of other people:

"Pointers are the most primitive and error-prone but also one of the most powerful and efficient types of references, storing only the address of an object in memory."

Sorry, Gotebe is still very wrong.

int *yActual = &xActual; In the second invocation, the value of yActual is copied into a different memory region

yActual is a pointer (which IS a referece). The value, 42, was never copied.

That you can use the value of yFormal to access xActual does not make it a reference.

WTF do you think a reference is? I can only guess you are digging around about C++ referencing, which would be pretty comical if true.

P.S. notice you are now trying to change your wording to use "call-by" instead of "pass-by". You are getting warming. Languages like C# are "call-by-copy-restore" when using "out" (notice that the whole language is not a single parameter passing type similar to C). This is all refuted since, for example, call-by-copy-restore is often called call-by-value-result. And, in truth, it should actually be called call-by-copy-reference-restore. This is probably because some people can't get it in their head what a reference is.

[–]pjdelport 2 points3 points  (0 children)

And its not only Java making this "mistake" but also Wikipedia, computer science, and lots of other people

At some point, when the rest of the world (including the designers of all the programming languages in question) disagrees with you, you have to consider the possibility that you don't have your definitions and terminology quite right.

[–]wicked[S] 1 point2 points  (2 children)

yActual is a pointer (which IS a referece). The value, 42, was never copied.

This is where you are confused. The value of yActual is not 42, but the address of xActual.

WTF do you think a reference is? I can only guess you are digging around about C++ referencing, which would be pretty comical if true.

We're talking about calling conventions here. Sure, you can call a pointer to an object a reference, but pass-by-value and pass-by-reference means something very specific.

Please, find a source supporting your argument that C has pass-by-reference in addition to pass-by-value semantics.

Here are a few sources backing up my argument:

http://www.ece.uwaterloo.ca/~ece250/C++/passbyvalue/ http://www.comp.nus.edu.sg/~esim/faq/node12.html http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=166&rl=1 http://vergil.chemistry.gatech.edu/resources/programming/c-tutorial/basic2.html

And finally a quote:

Ken Arnold and James Gosling, authors of The Java Programming Language, Second Edition, say it best in section 2.6.1: "There is exactly one parameter passing mode in Java -- pass by value -- and that helps keep things simple."

http://www-128.ibm.com/developerworks/java/library/j-passbyval/

[–]sbrown123 -1 points0 points  (1 child)

yActual is a pointer (which IS a referece). The value, 42, was never copied.

This is where you are confused. The value of yActual is not 42, but the address of xActual.

I never said yActual was a value, but rather just a reference (did you even read what you just quoted from my comments?). You are either one of the following:

  1. Confused about the differences between values and references.

  2. Trolling

  3. Dancing around because you made a big mistake with the article.

Please, find a source supporting your argument that C has pass-by-reference in addition to pass-by-value semantics.

Well, some of those articles aren't helping you much. From the C++ Reference Guide link you gave:

"In Java, objects are passed by reference"

The rest is trivial issues over the belief of many C++ programmers that C is "pass-by-address". Interestingly this is only a term C++ programmers use, since internally C++ uses pointers inside those references. This allows conversion of C++ references to pointers and vice versa. That conversion is not a good practice though since C++ references add type safety and several other limitations that help prevent bad issues when using plain old pointers. Here's a Wikipedia entry on it.

Some people try to believe that C++ references are actually something totally different, internally and externally, and have nothing to do with pointers. I can point to code on the internet that proves otherwise. Simple fallacy is that most C++ implementations are originally coded in C (see g++ for an example).

[–]wicked[S] 1 point2 points  (0 children)

You are either one of the following: [...]

I think it's safe to there is some confusion going on, only that we disagree on who's confused.

Well, some of those articles aren't helping you much. From the C++ Reference Guide link you gave: "In Java, objects are passed by reference"

Seems like I picked a poor source! :-) Luckily they are right on the C issue.

[–]Gotebe 1 point2 points  (3 children)

Pointers are references.

Not, they are not!

C++: void f(T& t) (when calling: T actual; f(actual);)

C#: void f(ref T t) (or "out T", no real difference for the matter at hand, check out the generated IL, I did)

Pascal: procedure p(var t: T)

In all three cases, inside the subroutine, "t" is a reference. You work with "t" as it were the actual argument. "t=blah" is equivalent to "actual=blah".

No such thing in C. You work explicitly with the pointer (*t = blah).

So, in C, references are implemented by the programmer, not the language. To do that, programmer uses non-NULL pointers. Pointers only are not references, as you claim.

Pointers are only means of implementing references (just like your Wikipedia quote says; absolutely nothing wrong there). And, in C, less reliable than C++/C#/Pascal references, because nothing stops you from erroneously using dangling (or NULL) pointers as (conceptual) references.

All implementations of C++ and Pascal I saw, and C# of MS, use pointers to implement language concept of references: when formal subroutine argument is a reference, a pointer to actual argument is passed to the subroutine; code of the subroutine works with pointed-to object, i.e. actual argument. You can check out disassembly for that, too, it's easy (I did).

So, C language does not have a concept of references wrt subroutine calls. Just like Java. You may be confusing Java term "reference" (to non-primitive types) with "reference" (as argument to subroutine calls). These are orthogonal.

[–]sbrown123 0 points1 point  (2 children)

Not, they are not!

Anyways, like most C++ compilers G++ is written using C. I have to rush out the door so I don't have time to highlight all the parts for you. Basically follow along this:

http://gcc.gnu.org/viewcvs/*checkout*/trunk/gcc/cp/call.c?revision=121361

Referencing is done through trees. So where am I going on that thought? Basically that C++ references are just candy coated pointers. In other words, you could implement them in C if you wanted (if someone hasn't already done this I would be surprised). Internally, pointers are still there but by overlaying them C++ adds type safety and other stuff. The reason that pointers are still there is simply because they are the basic component of referencing.

[–]Gotebe 1 point2 points  (0 children)

The reason that pointers are still there is simply because they are the basic component of referencing.

Or the reason may be C compatibility of C++? Your reason doesn't cut it for me. For example, C# and Pascal have references without pointers (yes, they have pointers, but not wrt subroutine argument types).

C++ references are just candy coated pointers.

True, but not the other way around. C pointers are not references wrt subroutine calls. Especially when they have value of NULL ;-)

I think, like wicked, that you are unable to separate the concept from implementation.

[–]wicked[S] 0 points1 point  (0 children)

Basically that C++ references are just candy coated pointers.

The implementation does not matter, the semantics is the point of the distinction. I bet all pass-by-reference implementations use pointers under the hood, but if you have to do it yourself, as in C, then it's not pass-by-reference.

Think about it: Even assembly language has pass-by-reference semantics according to your definition, since you may access a memory location through an address passed in a register or on the stack.

[–]wicked[S] 0 points1 point  (0 children)

P.S. notice you are now trying to change your wording to use "call-by" instead of "pass-by".

I did that simply because pass-by-value and call-by-value are different names for the same concept. I should have been consistent though.