Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

So to summarize, you have a Java function:

  public void f(Foo bar) { ... }
Which is the equivalent C++ function?

  void f(Foo bar) { ... }
  void f(Foo& bar) { ... }
  void f(Foo* bar) { ... }
It's the last one. Java passes everything by value, but non-primitive objects in Java are actually pointers (which Java inaccurately calls references), and the pointer is passed by value.


C(++) may not be the best choice for elucidating this issue, given the way arrays decay to pointers.

Instead of comparing Java to any other language, would it not be simpler to just say what Java does?


Why is it inaccurate to call it a reference in Java?

You don't dereference a variable in Java to access it, so that would make me think reference, not pointer.


By you do deference object variables in Java. What do you think the "." operator does?


Ah, true... so what is the difference between a reference and a pointer then?


It depends on which definition of "reference" you are talking about.

Pass-by-reference and C++ references are basically the same - aliasing without requiring dereferencing via an operator.

Java object references are like C++ pointers.

Java is pass-by-value (no aliasing) for all values (ints, bools, object references etc). Java has no object values.


'a.b()' dereferences 'a' to call its 'b' method. If 'a' is null you'll get a NullPointerException.


Alternatively, the NullPointerException could be viewed as a simple leakage of implementation details, which is a common issue with exceptions.


Actually it is somewhere between the last two. I cant do pointer math but i can pass a null reference.


But you can't write into the pointer variable itself from inside the callee:

    static void f(Foo x) {
      x = ...;
    }

    // somewhere
    Foo y = ...;
    f(y);
The pointer value of y cannot be changed from inside f. Therefore Java is pass-by-value.

Java also has restricted semantics on pointers, but that has nothing to do with the calling convention.

(Edit: Note that the object which y/x points to can be changed, but that's not the question.)


So would you assert this is not pass-by-reference?

    void f(const Foo& x){
    ...
    }
My point is the semantics don't map 1:1. If you're going to say Java's references are pointers with different semantics how is that semantically different from saying Java's references are references with slightly different semantics?


Semantics don't have to map 1:1 to still have a meaningful relationship.

Java object references are mostly like C++ pointers. Even though you can't do arithmetic on them, the way they behave during assignment and parameter passing is identical. The primary qualities of a pointer are that it points to something, copies of it are shallow (and cheap) and point to the same thing, equality of pointers implies equality of the objects (but not vice versa), etc. All the same in both languages.

Nothing in Java is like C++ references (except the word reference) because the primary qualities of references are that they alias the objects that they refer to, they can not be rebound, and operations on them act exactly the same as operations on the aliased objects, with no dereferencing operators necessary, including assignment.

Once you understand that, you can begin to grasp how Java can be fully pass-by-value and yet your function can modify a list and the caller will see the change.


Making the referenced object const doesn't change anything. Fill in the '?':

  void f(Foo* x) { Foo y; *x = y; }
  void f(Foo& x) { Foo y; x = y; }

  void f(const Foo* x) { const Foo y; x = &y; }
  void f(const Foo& x) { const Foo y; ?; }


my cpp foo is much out of date admittedly. I believe my comment explicilty deals with its parent comment. I believe your example you are setting the contents of a specific memory address. This is nonsensical in a java context. Again another example of how semantics dont map 1:1.


They do map 1:1, that's the point:

  void f(Foo* x) { Foo* y = new Foo(); x = y; } // C++
  public void f(Foo x) { Foo y = new Foo(); x = y; } // Java
If 'x' was a reference then you couldn't do that.


Except x could be an array


Except you still have no way to modify the variable binding on the caller's stack. This is what all of us in the "Java is call-by-value" camp keep yammering on about: changing a value on the heap (an array or object in Java) is not the same as changing a variable on the stack (a local variable in Java). In Java, you can never touch local variables on parent functions' stacks, therefore, Java cannot be considered pass-by-reference.

The rest of it (const, const_cast, arrays-are-kinda-pointers in C++, taking the address of stack variables, etc.) are just weird quirks in the language semantics. (Honestly, C++ is already a quirky enough language on its own to make detailed comparisons inherently problematic.)

At the most fundamental level, C++ supports both call-by-value and call-by-reference, while Java only supports call-by-value.


I get what you're saying.

I'm just saying philosophically if you're going to say it is pass-by-pointer w/ castrated pointers is that any different than pass-by-reference with castrated references?

To blur the lines: If escape analysis is enabled its entirely possible for an object to allocated on the stack. In this situation a callee could manipulate the parent stack. Granted it can't overwrite the entire region wholesale, but you could functionally overwrite it all, but java doesn't have any way of doing that semantically anyway.


    void f(const Foo&_x){
      Foo& x=const_cast<Foo&> (_x);
      …
    }
What do you think is going on here?


> What do you think is going on here?

I think you're adding code that doesn't address my point. This is pointer manipulation, not function call semantics. If you have raw pointers you can do a lot of magic. I think your code actually demonstrates how not-pointer like Java's references actually are.


This! People say java passes by reference sometimes, but in C++ the references can't be null whereas in java they can.


Cpp and c also call things volatile for entirely different reasons than Java.

These are two distinct ecosystems. They use the same terminology with different meaning. That perhaps is confusing, but definitely doesn't make one or the other incorrect.


I think this is the big thing. Maybe java references arent cpp refs. Is there a proper name for an abstract construct that refers to something else? Maybe reference?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: