Differences between C++ and Java

T

Thomas Hawtin

Roedy said:
If you ever coded in PDP-11 assembler you can see where some of C's
features came from, including 16 bit indexing,
auto-pre/post/increment/decrement and use of pointer arithmetic
instead of indexing.

"People often guess that they were created to use the auto-increment and
auto-decrement address modes provided by the DEC PDP-11 on which C and
Unix first became popular. This is historically impossible, since there
was no PDP-11 when B was developed. The PDP-7, however, did have a few
`auto-increment' memory cells, with the property that an indirect memory
reference through them incremented the cell. This feature probably
suggested such operators to Thompson; the generalization to make them
both prefix and postfix was his own. Indeed, the auto-increment cells
were not used directly in implementation of the operators, and a
stronger motivation for the innovation was probably his observation that
the translation of ++x was smaller than that of x=x+1."

-- Dennis M. Ritchie, "The Development of the C Language"

http://cm.bell-labs.com/cm/cs/who/dmr/chist.html
 
D

Dimitri Maziuk

Roedy Green sez:
First of all you mean primitives not natives, and both references and
primitives are passed by value. See
http://mindprod.com/jgloss/callbyvalue.html

It says: "can change the fields in the caller's objects", so how is
that a pass by value?

I don't care about the reference, I care about the object behind it.
The important part is that caller code can modify the object I've
passed to it, so the object is a "var" parameter.

As for that "reference" thingy itself, Java can pass it by carrier
pidgeons for all I care.

Dima
 
D

Dimitri Maziuk

Roedy Green sez:
What "magic" are you talking about? do you mean a hidden flag to use
for live tallying?

Whatever's needed for paticular gc implementation.
(E.g. a reference-counting gc would need a reference counter.)

Dima
 
L

Luc The Perverse

AndyRB said:
My comments:
"In Java, the sizes of int, long etc. are rigidly defined in terms of
bits. In C++ they are platform-dependent. "

Technically this is inaccurate as the sizes of built-in types in c++
are *implementation* defined and the standard also specifies the
miniumum sizes of types and the size relationship between then:
char - 8 bit, -127 to +127 when signed
short - plus or minus 32767 (2**15)
int - plus or minus 32767
long - plus or minus 2147483657 (2**31)

char <= short <= int <= long.

"In Java, garbage collection of unreferenced objects is automatic. In
C++, you manually manage memory. In Java you don't know for sure that
all finalizers will be run; in C++ you do, because you invoke them
manually. You could of course write a manual close method for Java
objects. In Java, the choice of stack of heap allocation is handled
automatically by the compiler (Sun's javac is not very bright always
using the heap for objects). In C++ you control it manually. "

There is more than one type of memory in c++, for example a variable
declared as having automatic storage duration will be automatically
managed (deallocated and destructor called). So it would be more
accurate to specify the type of memeory, i.e. memory is manually
managed when using dynamic memory. There are no finalizers in c++ and
although there are destructors which you can invoke manually
"ObjectName.~classname()", doing so would often result in undefined
behaviour (very rarely done except in low-level code - i.e.
implementation of std::vector).

"In Java, references are constrained to point only to the beginnings of
objects. In C++, you can do arithmetic on pointers and make pointers
point anywhere in the address space. "

I understand what you are saying here, but in c++ you can legally only
point to an object or one past the end of a object, otherwise you have
undefined behaviour. But obviously it is up to the programmer in this
case to ensure they do not invoke undefined behaviour, the language
will not enforce/check this.

"Java checks all subscripts that they are in bounds and all casts for
validity. C++ does not. "
You are right that C++ does not check *all* subscripts and *all* casts
but it does check some. For example, when using c++ style casting,
rather than a traditional C cast.

"Java has a vast standard library set, including AWT and Swing. C++ has
a relativey modest standard set of methods, and relies on
platform-specific GUI libraries."

A difference you could mention the fact that the c++ standard library
is typically more template / generic based rather than object oriented.
The library is implemented in standard c++, therefore anyone can
provide third party libraries that work just as well, so although it
would be good if more functionality was standardized, it is not
necessarily required.
The fact that the c++ standard library is part of an ISO standard and
must be portable across many "platforms" which have far less
requirements than the JVM (i.e. no requirement for a display or hard
drive), certainly makes a difference. The library and the language
satisfy only the core requirements and has a far more limited scope
than the Java library. Third party library play an important part in
c++ and always will.

"In C++ constructors inherit. In Java, constructors are redefined for
every subclass."
This is not true, constructors in c++ do not inherit.

"Java has the final keyword and C++ has const. C++ gives you finer
control, but that control can be overridden with a cast. "
Not really. In c++ you can usually always lie to the compiler, but...

const int const_val = 5;
int & val_ref = const_cast<int&>(const_val);
val_ref = 6; //undefined behaviour.

In the above the const cast is OK, but the underlying variable
const_val remains const (it may, for example, have been place in an
area of memory marked as read-only). The result is any attempt to
modify it is illegal - undefined behaviour.

Other main differences:
- c++ the language and it's standard library are defined by a ISO
standard.
- deterministic destruction (this is very important from a c++ point of
vioew).
- exception handling and specifically exception specifications
- different philosophies / goals.

While I have no doubt that you are competant and know what you are talking
about, the criticism of the document on Roedy's site seems a little nit
picky.
 
B

Bjorn Abelli

It says: "can change the fields in the caller's objects", so
how is that a pass by value?

I think you have misunderstood what Java means by "value" and "reference" in
this case.

When you're talking about primitives, what is passed is the actual value of
the primitive. When you're talking about objects, the *value* that is passed
is a *reference* to the object.

As such that value refers to the same instance as the caller, and hence you
can "can change the fields in the caller's objects", but you can't *replace*
the caller's objects.

If it really had been passed "by reference", you would also have had e.g.
the possibility to change the original "reference-holder's" value for a
reference to *another* object, much like you can do in C/C++ and the likes.

It's an important distinction.

// Bjorn A
 
B

Bjorn Abelli

"AndyRB" wrote ...

This was one of the things that amused me when I programmed in C/C++ many,
many years ago, that a "long" not necessarily needed to be "longer" than an
"int"... ;-)

I'm not sure that you by "implementation defined" actually mean anything
else than Roedy does with the phrase "platform-dependent". The term
"platform" can unfortunately mean several things, not only OSs and such,
depending on the context it's used in.

AFAIR I could even use different definitions for the primitives within *the
same environment*, depending on the switches I set for the compiler...

Which I had to do in some cases to get the same results of the code when I
moved it between different compilers.

So you could easily say that the primitives in C++ are dependant on even
*more* things than just the "platform"...
While I have no doubt that you are competant and know what
you are talking about, the criticism of the document on Roedy's
site seems a little nit picky.

I usually give folks the benefit of a doubt, and I believe and hope that the
"criticism" you're talking about, rather is an expression of gratitude
towards Roedy, as it can clarify things, and make Roedy's pages even better
than they already are, when there are valid pointers coming up in the
discussion.

I also believe Roedy has the discretion to decide for himself which of the
comments he wants to include or weed out.

// Bjorn A
 
M

megagurka

Dimitri said:
Roedy Green sez:

Whatever's needed for paticular gc implementation.
(E.g. a reference-counting gc would need a reference counter.)

I don't see why a Java GC would require any more "magic" than the
vtable needed for virtual dispatch in C++. No modern GC implementation
uses reference counting.

/JN
 
B

blmblm

Roedy Green sez:

It says: "can change the fields in the caller's objects", so how is
that a pass by value?

Because what is being passed is not an object, but a *reference to
an object*, where "reference" is to be understood as "Java's nearest
analogy to pointer" rather than whatever is meant by "reference" in C++.
I don't care about the reference, I care about the object behind it.
The important part is that caller code can modify the object I've
passed to it, so the object is a "var" parameter.

The object is not a parameter at all.

One of the critical distinctions between Java and C++, at least
from the point of view of helping people coming to Java from C++
get acclimated, is this:

In C++, if you have a class MyClass, the line

MyClass obj;

declares a variable that's an instance of MyClass, and allocates
space (on the stack, usually?) for a MyClass object. If I remember
my C++ right, it also creates the object by calling the no-argument
constructor.

In Java, the same line declares *a reference to a MyClass object*.
The nearest C++ analog is

MyClass* obj;

No MyClass object is created until one writes something such as

obj = new MyClass();

IMO, it's sloppy terminology to talk about passing objects as
parameters to Java methods, because in Java you can't do that.
What you're doing is passing *references [ "pointers" ] to objects*.
It's analogous to passing, in C++, a pointer to an object.

In C++, if you pass, by value, a pointer to an object, both the caller
and the callee can change the value of the pointed-to object. That
doesn't make this pass by reference, because what's actually being
passed is a copy of a pointer; changing the callee's copy of the
pointer doesn't change the caller's copy. It's the same in Java.

So, C++ gives you two ways of referring to objects (directly and
through pointers), while Java only gives you one (through its
version of pointers, "references"). The Java syntax for referring
to objects by way of references to them unfortunately looks like
the C++ syntax for referring to objects directly.

I think a lot about Java makes more sense, coming from C++, if
you can make the following mental transformations:

Java:

MyClass obj;
obj = new MyClass();
obj.method();
obj.field = value;

C++ (apologies if I don't get this exactly right -- I'm a bit rusty):

MyClass *obj;
obj = new MyClass();
obj->method();
obj->field = value;


This "pass by reference versus pass by value" discussion is a hardy
perennial in these parts, as you may or may not know. Some C++
programmers don't seem very amenable to the argument that Java
passes everything by value (but you have to understand what's being
passed), so perhaps you won't find this convincing. My two cents'
worth, though.
 
R

Roedy Green

It says: "can change the fields in the caller's objects", so how is
that a pass by value?

The REFERENCE is passed by value. You can't make the caller's
reference point to a different object.

You can't pass objects in Java, only references to them.

quoting from http://mindprod.com/jgloss/callbyvalue.html

When you call a method, the method sees a copy of any primitives
passed to it. Thus any changes it makes to those values have no
effect on the caller's variables. This also applies to references
passed as parameters. The caller cannot change the caller's reference
variables, i.e. make them point to different objects, but it can
change the fields in the caller's objects they point to. In Java, you
cannot pass objects as parameters, only references to objects.

quoting from http://mindprod.com/jgloss/callbyreference.html

When you call a method by reference, the callee sees the caller's
original variables passed as parameters, not copies. References to the
callee's objects are treated the same way. Thus any changes the callee
makes to the caller's variables affect the caller's original
variables. Java NEVER uses call by reference. Java ALWAYS uses call by
value.

How do you fake call by reference in Java, or more precisely, how can
a callee influence the values of it's caller's variables?

1. Use a holder/wrapper object passed to the callee as a parameter.
The callee can change the object's fields. That object may be as
simple as an Object[]. In Java, a callee may change the fields of a
caller's object passed as a parameter, but not the caller's reference
to that object. It can't make the caller's variable passed as a
parameter point to a different object. It can only make its local copy
point to a different object. A holder class is just a class with
fields to hold your values. It has no methods other than accessors for
the fields.

2. Have the callee return the new values, perhaps wrapped in an holder
class or Object[], and have the caller store them away somewhere.

3. Communicate via a static or instance variable visible to both
caller and callee.

4. Use a delegate object. The callee calls its methods to save the
results for the caller.

Dale King points out that attempts to fake call by reference are
usually a sign of poor object-oriented design. A function should not
be trying to return more than one thing. He uses the term "thing"
because it is proper to return more than one value (e.g. returning a
Point that contains two values). If you are trying to return two
values, the test he like to apply is whether you can come up with a
logical name for the values as a group. If you can't, you had better
look to see if maybe you what you have is really two functions lumped
together.
 
R

Roedy Green

I don't care about the reference, I care about the object behind it.
The important part is that caller code can modify the object I've
passed to it, so the object is a "var" parameter.

As for that "reference" thingy itself, Java can pass it by carrier
pidgeons for all I care.

That is C thinking where you can pass Objects applied to Java where
you can't. We have been round this mulberry bush hundreds of times
before, and in the end, the consensus always forms that the clearest
path to understanding is to focus on the fact that references, not
objects are passed, and they are passed by value. Everything is passed
by value, without exception. Study how the JVM works by disassembling
some code. See http://mindprod.com/jasm.html if you are skeptical.

Since objects cannot be passed as parameters, they are passed neither
by reference nor by value.
 
R

Roedy Green

Yes, Java is so bulletproofed that to a C programmer it feels like being in a
straightjacket, but it's a really comfy and warm straightjacket, and the world
would be a safer place if everyone was straightjacketed most of the time.
-- Mark 'Kamikaze' Hughes

That is true, but only when you are new and don't know the Java
idioms. You keep trying to do everything by the familiar "cheating"
platform dependent techniques familiar from C. Once you "go straight"
and accept you are writing platform-dependent code, that feeling
gradually goes away.

A better analogy would be a C programmer is like a thief on probation
whose first inclination is to cheat/steal. One he gradually learns
alternative ways of getting the desired effects without cheating, the
law no longer feels like a straightjacket.

I started out in C/C++ myself before switching to Java. The straight
jacket effect is definitely real, and infuriating when you know some
simple C or assembler would do the job with seemingly only the
craziest circumlocutions in Java to get the same effect.

It is a bit like learning French. You have to stop trying to
translate word for word, and express yourself with the French idioms
you know.
 
R

Roedy Green

Whatever's needed for paticular gc implementation.
(E.g. a reference-counting gc would need a reference counter.)

Reference counting is not used in any Java GC I have heard of.
Primitive ones use Mark and Sweep. Fancier ones use generational
collectors, and Sun uses a tweakable combination. See
http://mindprod.com/jgloss/garbagecollection.html

Reference counting is very slow and can't deal with circular
references.
 
R

Roedy Green

Yes, Java is so bulletproofed that to a C programmer it feels like being in a
straightjacket, but it's a really comfy and warm straightjacket, and the world
would be a safer place if everyone was straightjacketed most of the time.
-- Mark 'Kamikaze' Hughes

once a wry comment. repetitively a troll.
 
R

Roedy Green

While I have no doubt that you are competant and know what you are talking
about, the criticism of the document on Roedy's site seems a little nit
picky.

Who is the document aimed at? Anyone who knows both languages already
has a list of grievances with both languages and would want them
highlighted.

The document is more aimed at someone who knows Java learning C++ or
the reverse to give them a roadmap of the major differences -- things
to watch out for. It is not designed to explain the feature
differences in detail. The problem with providing too much detail is
the novice goes away even more baffled that when she started.
 
R

Roedy Green

I usually give folks the benefit of a doubt, and I believe and hope that the
"criticism" you're talking about, rather is an expression of gratitude
towards Roedy, as it can clarify things, and make Roedy's pages even better
than they already are, when there are valid pointers coming up in the
discussion.

I welcome comments of the form:

"Link X is broken. I think it should be Y."

"I could not understand X in your Java glossary."

"You stated X which is untrue. According to Y, this is so."

"You stated X which is untrue. That can't be so because when you run
the attached program ...."

"You stated X which is ambiguous. It could mean Y or Z."

"Could you please write an entry on X?"



I am not particularly keen on comments of this form:

"Your glossary is a bunch of infantile crap. 90% of it is wrong. You
should be shot for wasting people's time."

"take your commie crap in the Java glossary and stuff it up your
nose."

"Your glossary is totally useless. I looked something up and I could
not find anything about it."

"the X site is way better than yours. You should give up your feeble
project. You don't know nothing."

"You are just in it for the money, you creepie commie."
 
R

Roedy Green

Once you "go straight"
and accept you are writing platform-dependent code, that feeling
gradually goes away.
oops
Once you "go straight"
and accept you are writing platform-INdependent code, that feeling
gradually goes away.
 
D

Dimitri Maziuk

Bjorn Abelli sez:
...

I think you have misunderstood what Java means by "value" and "reference" in
this case.

No.

What Programming 101 means is "by reference": caller may modify the
parameter, "by value": caller may not modify the parameter.

Like I said, Java may call it "pass by Santa via the chimney" -- that
won't change the fact that all objects in Java are passed by reference
in Comp. Sci. terms.

Dima
 
A

AndyRB

Roedy said:
A C++ pointer can also point into the middle of an array or string, or
use a byte pointer to the low or high bytes of an int. These are all
allowed by the compiler and generate working code.

That is correct.

What is probably confusing here is that in c++ an object is defined
only as a region of storage, so in the cases you note above the pointer
is always pointing at a valid object. The bit I thought was a a little
misleading was:

"In C++, you can do arithmetic on pointers and make pointers
point anywhere in the address space"
 
A

AndyRB

Roedy said:
So the compare one of the stripped down Java's with C++. Lack of
libraries can't be considered a virtue.
Do you mean lack of *standard* libraries??
Either way I would agree with you, but c++ certainly doesen't lack
libraries.
If you wanted you could
ignore the Java libraries and write your own too. IBM wrote SWT.

But in c++ you can write your own libraries using only c++, with
assignment operator, subscript operator, etc. and with get very good
efficiency.
 
A

AndyRB

Luc said:
While I have no doubt that you are competant and know what you are talking
about, the criticism of the document on Roedy's site seems a little nit
picky.

To be fair many of the comments were nit picks, but I'm sure Roedy will
be able to decide how important each point is, however some of the
points were definitely not nit picks, for example...

"In C++, you manually manage memory. In Java you don't know for sure
that all finalizers will be run; in C++ you do, because you invoke them
manually." ... "In C++ you call your destructors manually"

This is simply incorrect.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top