Letters to the editor may be sent via email to [email protected], or via the postal service to Letters to the Editor, C/C++ Users Journal, 1601 W. 23rd St., Ste 200, Lawrence, KS 66046-2700.
The following two letters are in response to the Editors Forum in the December 2000 Java Solutions supplement to C/C++ Users Journal. I had asked readers whether they felt Java made them more productive. As you can see, your mileage may vary. mb
Hello,
Well, I started using Java at the university because I wanted to learn it, so I asked one of my teachers if I could present my project in Java and he agreed. Being a longtime C++ devotee since 1994, I have kept up to date with the C++ Standard and lost some interest in the language when I started to see it grow and grow. So I went into the Java hype and learned Java. Nowadays I continue to be a C++ devotee for speed-critical applications like computer graphics, but use Java for other kinds of applications.
About the P word, yes Java does improve productivity. I started to care less about memory allocation, thanks to the GC. But it isnt only that, because Java uses exceptions for all errors, not things like return -1, return 0, throw exception, and so on, that live in the C++ world. So I know that an error usually means an exception. Compare that with C++ where I can make a program with exceptions and then compile without exception support. Another reason is that if I make a Java program with JDK version X, I know that it will compile and run (or just run :) ) on any Java platform that supports JDK X. But that is not the case with C++; how many concessions do we have to make in order to be able to able to compile the program on multiple platforms? I know because in my work I develop programs that must run in several versions of Unix and Windows.
So if using Java means spending less time finding workarounds for each compiler, using exceptions in a coherent way, being free to use language features without worrying if compiler X will support it, not having to spend days trying to find if a memory problem is related to my application or a third-party library, then yes Java makes me more productive.
Paulo Pinto
uRD Software Engineer
Mr. Briand,
In your December Editors Forum, you made a call asking to hear from experienced C++ programmers who have taken up Java, asking whether were more productive in Java and what our reasons are for using it.
I am a GUI engineer, having started with programmatic C APIs and later moving to C++ GUI development frameworks, including MFC and BeOS. Im currently project manager at TimeLine Vista, Inc. (http://www.timelinevista.com) developing a cross-platform C++ GUI framework for targeting MacOS, Windows, and BeOS. The subjects of GUI design and what constitutes a good framework for multithreaded application development are my forte.
When I started at TimeLine, my second task was to write ViewNet Audio, a multi-platform (MacOS and Windows) GUI application for controlling our line of audio dubbers via ethernet. Given that no acceptable cross-platform solution existed, we opted to use Java, taking the promise of portability and quality at face value. While Java did live up to the portability promise, I found it lacking in every other area.
First and foremost is the performance. For writing a real application (i.e. anything more than a web applet) Java has proven to be woefully inadequate. If you look at the screen shots on the TimeLine web site, youll find that ViewNet may well be the largest scale Java application ever written. Weve received comments from outside the company to that effect. Were lucky to get four frames a second rendering a 24-track audio project while in play, even without displaying waveforms for the audio, and having made severe compromises in the cleanliness of the code (caching calculations, etc.) to achieve even acceptable performance. Addition of waveforms is the next requirement for this product, and its out of the question because their display would take the performance below its current barely acceptable level. Even the hope for native code generation from Java has failed to materialize.
Second is the threading and synchronization model: its terrible. Absolutely terrible. The fact that asynchronous dialogs dont exist means that a given window event loop, if it needs to present a dialog to the user, will block waiting for that dialog, but meanwhile, another event loop is spawned to deal with events for that window in effect the window has two event loops going simultaneously, and if a dialog blocks the inital event loop in a synchronized method, a deadlock is virtually guaranteed. This is merely one manifestation of an atrocious synchronization model. The fact that the equivalent of a semaphore is the synchronized keyword means that all synchronous operations must be atomic: you cant lock an object, act on it, then unlock it. This imposes design requirements which tie the hands of the application developer and can harm the cleanliness of code involving synchronization.
Third is the unreliability. Time and time again Ive seen the JVM lock up for no apparent reason. Ive seen data corruption in socket read/write operations. This issue alone has rendered unusable a substantial amount of work done to allow network backup of projects from the audio dubber to the Java client.
There are many other issues as well the lack of unsigned types causes code extracting data structures from buffers received from the ethernet connection to be bloated with superfluous upcasts with &0xFF to get the real value. The lack of separation of interface and implementation means the entire implementation of a given object must be imported to build an object which depends on it, causing compile times to increase exponentially rather than linearally as the number of files in a project increases. I could go on, but I think the point is clear. We at TimeLine have decided to abandon the Java version of ViewNet and never use Java for anything again. Thats why Im managing the C++ GUI development framework project: as a foundation for replacement of the failed Java experiment.
Yours truly,
Brian Tietz
Dear CUJ,
The article by Andrew [Koenig] and Barb[ara Moo]: "Using Library Algorithms," published in January 2001 edition of CUJ is interesting. It has motivated me to see their Accelerated C++ book.
In the paragraph that explains the not_url_char function, I found a sentence which I believe does not conform with the C++ Standard. It was written:
Thus, we will create and initialize the string url_ch only on the first call to not_url_char.
I believe "creation on the first call" is improper. It violates the following sections of the C++ Standard:
- 3.6.2 Initialization of non-local objects
- 3.7.1 Static Storage Duration
- 6.7 Declaration statement
Hans Dulimarta, Ph.D.
[email protected]
Andrew Koenig replies:
Clause 3.6.2 is not relevant to the behavior of this particular piece of code, because url_ch is a local object, not a non-local object. Because it is a local object of static storage duration, it is initialized as specified in clause 6.7.
Clause 6.7, paragraph 4, in turn, says that url_ch is zero-initialized before any other initialization takes place (i.e., all of its member data are set to zero at the beginning of the program), and then it is "initialized the first time control passes through its declaration." In other words, the variable url_ch is given its final value as part of what happens during the first execution of not_url_char.
Therefore, I think that "only on the first call to not_url_char" is a pretty accurate description of what the Standard says should happen.
Am I missing something? Andrew Koenig
Hans Dulimarta replies:
OK, regarding this clause [3.6.2] it was my mistake to overlook the local static attribute of url_ch.
As for initialization, I agree with you that it will be initialized the first time control passes through its declaration. The point in the previous e-mail was regarding the creation. I believe clause 3.7.1 implies that static variables have program lifetime duration. So, they should have been created before the first call.
The sentence in the paragraph of the CUJ article create and initialize the string ... on the first call ... implies that the string is:
1) created on the first call
2) initialized on the first call.
Again, I agree with you that 2) is correct. Hans Dulimarta
Andrew Koenig replies:
Ah, I see your point. Youre taking "create" to mean "allocate memory for," and Im using "create and initialize" to mean "construct with a specified initial value."
I believe that it is quite difficult to write a program that is capable of distinguishing between those two interpretations. In other words, suppose we have a function:
void f() { static T x; }
How might we go about writing a program that is capable of determining whether the implementation allocates memory for x at the time the entire program begins executing, or immediately before it constructs x? Offhand, I cant figure out a way to do it, because there is no way of even uttering the name of x outside the scope of f, or even inside that scope until after the definition of x and, once youre past that definition, x has already been constructed.
In order to make it clear that when we say "create" in this context, we mean "construct," were going to change "create" to "construct" in that paragraph in the third printing of Accelerated C++. If you like, we can include your name in the list of people on the www.acceleratedcpp.com site who reported corrections to the book.
Regards,
Andrew Koenig
Hi:
Just a thought. I read quite a bit about programming in C/C++ and I do it for a living. I wonder however, about the absence of books on using the NMAKE tool and Makefiles for compilation. Are there any you could recommend? I realize that most people use the IDE (I always have) but I would like to be more familiar with the workings in the background. Thanks.
Mr. Medina
Well, you have to admit, its not the sexiest topic for a book. But maybe some of the command-line gurus out there can recommend some good sources. Anybody? mb