**FIRST EMAIL**/Java and Orbit Balls *****JAVA DISCUSSION***

Greetings Teams:

In the 2010 season, FRC teams will have the option of programming their robot in Java. The addition of Java as a programming language option is the culmination of work by Worcester Polytechnic Institute (WPI) and researchers from the Sun SPOT project at Sun Microsystems Laboratories. To learn more as you wait for the 2010 season to begin visit http://www.sunspotworld.com/frc/Welcome.html ]http://www.sunspotworld.com/frc/Welcome.html and http://first.wpi.edu/FRC/frc-programming.html ]http://first.wpi.edu/FRC/frc-programming.html.$@# We’ll be updating both locations as details are finalized.

If you are planning to hold an off season event or host a demonstration of your robot over the summer, you might want some extra game pieces. Used orbit balls (the ones that survived championship) are available for purchase starting today here http://logoloc.com/first/ ]http://logoloc.com/first/ Quantities are limited. If you are borrowing a FIRST field for your off season event, please remember that game pieces are not included in the loan.

Go Teams!

How much better is JAVA going to be than Lab view?

Is it easier to use?

I think it is easier to make a fair comparison between C++ and Java than LabVIEW and Java. LabVIEW/[Java or C++] arguments are really more a matter of preference.

For FRC robotics, I prefer LabVIEW. For my neural-networks research, Java was the clear choice.

Yuck, java. The lack of pointers is a major turn-away for me.

However, for those high schools that offer AP computer science, the fact that the robot can now be programmed in java sorta bridges the learning gap a bit.

What is it that you want to do with pointers that Java’s pass by reference system can’t do exactly?

Pointer arithmetic. It can be useful if used properly. However, I wouldn’t encourage students new to C++ to use pointer arithmetic on the robot, unless of course, you want them to experience the frustration of the dreaded “Seg Fault”.

Proper pointer arithmetic can result in small and efficient implementations of some data structures and algorithms, but given (a) the scope of a typical FIRST program and (b) the fact that we now have hardware and compilers that often get the job done just as fast and without the difficult-to-debug errors, I would probably expand “students new to C++” to “just about anyone without a really convincing reason”. ::ouch:: :yikes:


char *ptr = malloc(SIZE);

ptr + i is equivalent to &ptr*. Both cases boil down to just a load effective address instruction. Besides the obvious that Java hides the virtual address of all values in the symbol table, I don’t see how you are missing anything by not being able to explicitly use pointer arithmetic. The point of pointer arithmetic is to compute the address of an element in an array. the “]” operator retrieves that element and many people find this interface more intuitive. There is no performance advantage of using pointer arithmetic and there is nothing you can’t do with the “]” that you can do with pointer arithmetic (as the “]” operator just encapsulates pointer arithmetic).*

The efficiency is not what you suggest it is. Pointer arithmetic adds the result of a multiplication too: addition and subtraction are scaled by the size of the structure pointed to.

But, at least in C, the size of the structure is a known quantity at compile time, so I would imagine that most of the time that multiplication can be eliminated by the compiler. And then on top of that, sometimes the multiplication will be by a power of 2, so the compiler will use a cheap shift operation.

And as I stated in my earlier post, both cases boil down to a simple lea instruction in assembly

See, here is a small piece of code I just wrote.


 1 #include <stdlib.h>
 2 
 3 int main()
 4 {
 5   int *array = malloc(10 * sizeof(int));
 6   int *ptr;
 7   int i;
 8 
 9   for(i = 0; i < 10; i++)
**10     ptr = array + i;**
11 
12   return 0;
13 }

and its assembly


0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 20          	sub    $0x20,%rsp
   8:	bf 28 00 00 00       	mov    $0x28,%edi
   d:	e8 00 00 00 00       	callq  12 <main+0x12>
  12:	48 89 45 f8          	mov    %rax,0xfffffffffffffff8(%rbp)
  16:	c7 45 ec 00 00 00 00 	movl   $0x0,0xffffffffffffffec(%rbp)
  1d:	83 7d ec 09          	cmpl   $0x9,0xffffffffffffffec(%rbp)
  21:	7f 19                	jg     3c <main+0x3c>
  23:	8b 45 ec             	mov    0xffffffffffffffec(%rbp),%eax
  26:	48 98                	cltq   
  28:	48 c1 e0 02          	shl    $0x2,%rax
  2c:	48 03 45 f8          	add    0xfffffffffffffff8(%rbp),%rax
  30:	48 89 45 f0          	mov    %rax,0xfffffffffffffff0(%rbp)
  34:	48 8d 45 ec          	lea    0xffffffffffffffec(%rbp),%rax
  38:	ff 00                	incl   (%rax)
  3a:	eb e1                	jmp    1d <main+0x1d>
  3c:	b8 00 00 00 00       	mov    $0x0,%eax
  41:	c9                   	leaveq 
  42:	c3                   	retq   

Alternate code


 1 #include <stdlib.h>
 2 
 3 int main()
 4 {
 5   int *array = malloc(10 * sizeof(int));
 6   int *ptr;
 7   int i;
 8 
 9   for(i = 0; i < 10; i++)
**10     ptr = &array*;*
11 
12   return 0;
13 }

its assembly


0000000000000000 <main>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 20          	sub    $0x20,%rsp
   8:	bf 28 00 00 00       	mov    $0x28,%edi
   d:	e8 00 00 00 00       	callq  12 <main+0x12>
  12:	48 89 45 f8          	mov    %rax,0xfffffffffffffff8(%rbp)
  16:	c7 45 ec 00 00 00 00 	movl   $0x0,0xffffffffffffffec(%rbp)
  1d:	83 7d ec 09          	cmpl   $0x9,0xffffffffffffffec(%rbp)
  21:	7f 19                	jg     3c <main+0x3c>
  23:	8b 45 ec             	mov    0xffffffffffffffec(%rbp),%eax
  26:	48 98                	cltq   
  28:	48 c1 e0 02          	shl    $0x2,%rax
  2c:	48 03 45 f8          	add    0xfffffffffffffff8(%rbp),%rax
  30:	48 89 45 f0          	mov    %rax,0xfffffffffffffff0(%rbp)
  34:	48 8d 45 ec          	lea    0xffffffffffffffec(%rbp),%rax
  38:	ff 00                	incl   (%rax)
  3a:	eb e1                	jmp    1d <main+0x1d>
  3c:	b8 00 00 00 00       	mov    $0x0,%eax
  41:	c9                   	leaveq 
  42:	c3                   	retq

Absolutely no difference whatsoever.**

This does not describe a difference between array indexing in Java and pointer arithmetic in C.

I don’t understand the point (!) of your example. What part of it should I focus on? None of it appears to show me a reason for preferring to use explicit pointers.

Plus explicit pointers make functions like swap (commonly used in bubblesort simple) simpler using C pass by reference…

Isn’t pass by reference exactly what Java lets you do in such cases? I guess I’m completely failing to understand what you’re trying to explain here.

I generated assembly for both of the examples with the relevant instructions bolded

.L2:
        cmpl    $9, -12(%ebp)
        jg      .L3
**        movl    -12(%ebp), %eax
        sall    $2, %eax
        addl    -4(%ebp), %eax
        movl    %eax, -8(%ebp)**
        leal    -12(%ebp), %eax
        incl    (%eax)
        jmp     .L2
.L3:
.L2:
        cmpl    $9, -12(%ebp)
        jg      .L3
**        leal    -8(%ebp), %eax
        addl    $4, (%eax)**
        leal    -12(%ebp), %eax
        incl    (%eax)
        jmp     .L2
.L3:

So 4 instructions are necessary for ptr = array + i; and only 2 instructions for ptr++; in this assembly language.

I Googled “java swap” and this site explains it pretty well. Basically when you pass by reference to a function in Java it gives the function a new (different) reference to the object and there is no way to change the original reference in the passing function. In C++, the pointer is like an absolute reference (memory location) that is the same everywhere and you can even use pointers to pointers (no references to references in Java).

and only 2 instructions for ptr++; in this assembly language.

So what’s your point? Of course an expression that contains multiple variables will generally be more complex then an expression that contains a single variable. ptr = (&(ptr[0])) + 1 will again compile to the same assembly. Array indexing is just an encapsulation for pointer arithmetic as I explained earlier. Any pointer arithmetic expression will have a matching array index expression and both of these expressions will compile to the exact same instructions.

I Googled “java swap” and this site explains it pretty well. Basically when you pass by reference to a function in Java it gives the function a new (different) reference to the object and there is no way to change the original reference in the passing function. In C++, the pointer is like an absolute reference (memory location) that is the same everywhere and you can even use pointers to pointers (no references to references in Java).

If you want to change a reference to an object, just have the method return a new reference. If you want a series of references, just encapsulate the references in objects. If you absolutely need to have access to the virtual address of an object, then Java just isn’t the right language for the job.

Here is swap with references:


public class MyInt {
	
	int data;
	public MyInt(int x)
	{
		this.data = x;
	}
	
	public static void swap(MyInt a, MyInt b)
	{
		a.data ^= b.data;
		b.data ^= a.data;
		a.data ^= b.data;
	}

}

You can’t dereference (&) and do pointer arithmetic like that in Java.

There is no matching array index expression for this:

ptr = 365;

Array indexing requires a symbol (base of array) and a type (size of element). When an integer can be cast to a pointer, pointer arithmetic can be done without an array.

I know you can create a new class, a similar example was on the page I linked. I just said it was simpler in C. Creating new classes or returning multiple references doesn’t sound simple to me.

Again, I understand both languages and the reasons why Java doesn’t allow explicit pointers (source of bugs, reference counting for garbage collecting, sercurity, etc…).

Lets revisit how this whole conversion happened (with me paraphrasing)
Billy: Yuck Java. Pointers ftw :smiley:
Jared: What cant you do with Java references?
Me: Pointer Arithmetic.
Jared: Granted, but you better have a good reason.
<Long posts involving example code by Chris, me and Alan>
I thought twice before pressing Submit Reply on my first post because I knew it wouldn’t be my last on this thread;) Programming debates are interesting (for me atleast) but time consuming. Maybe I should have just let Billy reply or learned from C++ vs LV threads.

Right. The whole discussion here is based on the lack of pointer arithmetic in Java. But I’m still trying to find out why some think that pointer arithmetic is more efficient than using arrays. My understanding is that they compile to exactly the same thing, since in C a is just syntactical sugar for *(a+i). I used to confuse people by writing i[a] instead, which gives exactly the same result.

There is no matching array index expression for this:

ptr = 365;

Without significant context, I’m at a loss to understand why you’d want to write it. With the exception of using memory-mapped I/O, I have yet to see any examples anywhere where using absolute pointers gives any improvement in efficiency over using arrays.**

More importantly, how much does it matter in our application? What difference will it make?