What exactly does “pass by reference” mean?

后端 未结 8 2185
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-30 03:15

And who has the authority to decide?

Edit: Apparently I haven\'t succeeded in formulating my question well.
I am not asking how Java\'s

8条回答
  •  忘掉有多难
    2020-12-30 03:57

    Sure, different people currently have different definitions of what "pass-by-reference" means. And that is why they disagree on whether something is pass-by-reference or not.

    However, whatever definition you use, you must use it consistently across languages. You can't say that one language has pass-by-value, and have the exact same semantics in another language and say that it is pass-by-reference. Pointing out the analogies between languages is the best way to address this dispute, because although people might have strong opinions about the passing modes in particular languages, when you contrast the identical semantics with other languages, it sometimes brings counter-intuitive results that force them to re-think their definition.

    • One predominant view is that Java is pass-by-value only. (Search everywhere on the Internet and you will find this point of view.) This view is that objects are not values, but are always manipulated through references, and thus it is references that are assigned or passed, by value. This view holds that the test of pass-by-reference is whether it is possible to assign to a variable in the calling scope.

    If one agrees with this viewpoint, then one must also consider most languages, including as diverse ones as Python, Ruby, OCaml, Scheme, Smalltalk, SML, Go, JavaScript, Objective-C, etc. as pass-by-value only. If any of this strikes you as strange or counterintuitive, I challenge you to point out why you think it is different between the semantics of objects in any of those languages from objects in Java. (I know that the some of these languages may explicitly claim that they are pass-by-reference; but it is irrelevant what they say; a consistent definition must be applied to all languages based on the actual behavior.)

    • If you take the opposing view that objects in Java are pass-by-reference, then you must also consider C as pass-by-reference.

    Take your Java example:

    class Thing { int x; }
    void func(Thing object){ object.x = 42; object = null; }
    Thing something = null;
    something = new Thing();
    func(something);
    

    in C, it would be equivalent to this:

    typedef struct { int x; } Thing;
    void func(Thing *object){ object->x = 42; object = NULL; }
    Thing *something = NULL;
    something = malloc(sizeof Thing);
    memset(something, 0, sizeof(something));
    func(something);
    // later:
    free(something);
    

    I claim that the above are semantically equivalent; only the syntax is different. The only syntax differences are:

    1. C requires an explicit * to denote a pointer type; Java's reference (pointers to objects) types don't need an explicit *.
    2. C uses -> to access a field through a pointer; Java just uses .
    3. Java uses new to dynamically allocate memory for a new object on the heap; C uses malloc to allocate it, and then we need to initialize the memory.
    4. Java has garbage collection

    Note that, importantly,

    1. The syntax for calling the function with the object are the same in both cases: func(something), without needing to do anything like taking address or anything.
    2. In both cases, the object is dynamically-allocated (it may live beyond the scope of the function). And
    3. In both cases, the object = null; inside the function does not affect the calling scope.

    So the semantics are the same in both cases, so if you call Java pass-by-reference you must call C pass-by-reference too.

提交回复
热议问题