Java Basics
Java 5.0 - Tiger: A Classic printf Snippet from the Past
Java 5.0 - Tiger: A Classic printf Snippet from the Past
Aug. 16, 2004 12:00 AM
I just downloaded J2SE 1.5/5.0 "Tiger" Beta and started playing with it. First, I could not get the Cheetah and the Tiger to play together.
For those who joined the game late (like me), Cheetah is the early preview of Eclipse's future support for J2SE 1.5. It is is not part of the Eclipse 3.0 release. If anyone got these two cubs in a cage and under control, please leave a comment or at least a link to how to make these two get along. Thanks in advance.
After a usual, HelloWorld program, I wanted to explore the new printf feature of the java.io.PrintStream. Given that this is advertised as the close cousin of C language's printf function, I thought I would put it to test and see how it is and is not similar to its C counterpart. This revealed some interesting observations that refreshed my Java fundamentals.
Let's start with a simple C code snippet. For those who attended some junior level C programmer interview, this is a familiar question. What is the output when the following code is executed?
int i = 0;
printf("%d %d %d", ++i, ++i, ++i);
If you were the interviewee and I am the interviewer and if you said "0 0 0" or "1 1 1" as the answer, I would let you go without wasting any more time. If you said the answer was "1 2 3", then I would have asked you to take another look at it. If you still didn't change the answer, I would have asked a fundamental question about how the parameters are passed between functions in C and in Pascal. That should ring bells somewhere and in order to proceed to my next question, you should change your answer to "3 2 1". Because in C the parameters are passed from right-to-left (commonly referred to as C calling sequence). If it were similar code in Pascal where the parameters are passed from right-to-left, the answer would be "1 2 3".
Okay. So much for the obsolete technologies. Now, in the latest bleeding edge Java 5.0, what would the following code print?
int i = 0;
System.out.printf("%d %d %d", ++i, ++i, ++i);
Is it "3 2 1"? or "1 2 3"? How are parameters passed to methods? We all know Java is strictly pass-by-value. But does it evaluate from right-to-left like C or left-to-right like Pascal?
The output of Tiger is "1 2 3". Trivial observation... given that Java is supposed NOT to be difficult and Sun is bent on "vbfication" of Java. As I was in the C++ mindset (thinking about Templates/Generics etc), for a second, I thought it would print "3 2 1".
Actually compiling the C code with -S option (if I remember it right) would generate the machine code that gives the appropriate mnemonics of the assembly. If you compare the outputs of differnt compilers on different platforms, these "++i" statements may get translated to three "INCR i" or three "ADD i 1" or if the compiler has a smart-ass optimizer, it may even do "ADD i 3" thinking that the programmer is a half-brain. Thus, I say that writing this type of code is a big no no. However, this sort of knowledge is useful in debugging/fixing/identifiying problems with the old C code.
If the compiler replaces all the ++i expressions with the result of "ADD i 3", the output would be "3 3 3".
About Chakra YadavalliChakra Yadavalli works as Principal Consultant for Keane, Inc based in
Boston, MA. Chakra holds a degree in Electronics and communications engineering
and has nearly 10 years of experience in developing distributed OO applications
in C++/Java for verticals such as telecom, government, securities and financial
services. If he is not working, he could be found in one of the New England
casinos practicing his blackjack skills and hoping that, some day, he would
join the MIT Black
Jack team. Check out his blog (http://jroller.com/page/cyblogue) for
more information.
#9 |
All the comments are very good. This entry is my blog entry. I just added a sidebar to it. Check it out.. especially Jason :-)
http://www.jroller.com/page/cyblogue/20040816#tiger_a_classic_printf_sni...
|
#8 |
Jason, it would be "platform dependent," bub. If you''re going to put something in print... ;-P
|
#7 |
Jerome Lanneluc commented on 17 Aug 2004
Chakra,
You can now ride the Cheetah easily. Just download the latest Eclipse milestone (namely 3.1 M1). Cheetah is now fully integrated in Eclipse 3.1 builds. It still cannot run full speed, and it has some limitations. For example, varargs are not supported yet. So you won''t be able to use System.out.printf(String s, Object ... args). But you can still experiment with generics.
Hope this helps,
Jerome
|
#6 |
Jason Kilgrow commented on 17 Aug 2004
I''m not sure what compiler or what platform you were using Chakra, but on my Tru64 machine at compile time I get:
cc: Warning: tester.c, line 4: In this statement, the expression "printf(...)" modifies the variable "i" more than once without an intervening sequence point. This behavior is undefined. (undefvarmod)
printf("%d %d %d\n", ++i, ++i, ++i);
----^
On my Redhat 9 machine I get no warnings at compile time but nothing prints either. That''s a little strange.
On AIX I get no compiler warnings and it prints "1 2 3".
On Windows NT I get no compiler warnings and it prints "3 2 1".
So, it appears to be platform independent.
I hope that my next interviewer asks me this quesiton so I can school him American style just like I schooled you, bub.
I''m no magazine author or editor but I think if I were, I would check my facts before I publish them.
Perhaps this isn''t the point of this article but if you are going to put something in print, you better make sure it''s accurate.
|
#5 |
Lois Goldthwaite commented on 17 Aug 2004
I wouldn''t hire any interviewee who thought this code was in the least acceptable. The compiler is allowed to evaluate arguments in ANY order, not necessarily left-to-right or right-to-left. The real problem is that i is being modified more than once between sequence points, and in C that produces "undefined behavior," which is by definition A Bad Thing.
|
#4 |
Scott Blankenship commented on 17 Aug 2004
I agree with everyone here. I would reject the lines in a code review as having poor readability/maintainability. This is along the same lines as the inevitable discussions of operator precedence in programming language classes. Does + or * get evaulated first? Who cares.... use parenthesis for readability.
|
#3 |
Chris Trobridge commented on 17 Aug 2004
I agree with J Yu: the C++ reference manual leaves the order of argument evaluation undefined and notes specifically that this differs between compilers. I''d be happier if he rewrote the code to avoid this uncertainty.
|
#2 |
Anas Mughal commented on 16 Aug 2004
If there is a developer on my team who has this level of knowledge, I would highly discourage them to write this kind of code. Other developers might not have the knowledge or experience to maintain this code.
|
#1 |
J Yu commented on 16 Aug 2004
I''ll hire someone if he said it''s undefined :) maybe it''s nice to have this kind of knowledge, but it''s never a good idea to have your code depending on this kind of knowledge.
|