# Eclipse-Fehler?



## Leroy42 (10. Jul 2006)

Ich habe gestern etwas sonderbares entdeckt.

Hier ein Code-Ausschnitt (eher sinnfrei) der nur zeigen soll,
wie Eclipse automatisch einrückt.


```
public class DreiN {
	static void dreiN(int n) {
		if (n<5) return;
		int m = n;
		while (true) {
			while ((m&1) == 0) {
				m >>= 1;
			}
			System.out.println(m);
			if (m<n) return;
			m = (3*m+1)>>1;
		}
	}
	public static void main(String[] args) {
		dreiN(27);
	}
}
```

Hier das Ganze ohne Block-Anweisung der inneren while-Schleife.

```
public class DreiN {
	static void dreiN(int n) {
		if (n<5) return;
		int m = n;
		while (true) {
			while ((m&1) == 0)
				m >>= 1;
				System.out.println(m);
				if (m<n) return;
				m = (3*m+1)>>1;
		}
	}
	public static void main(String[] args) {
		dreiN(27);
	}
}
```

Wie man sieht, bekommt Eclipse die korrekte Formatierung
nicht geregelt, allerdings wird das Programm korrekt übersetzt.  :autsch: 

Hab' ich jetzt Tomaten auf den Augen und etwas übersehen?
Oder wo kann man die Eclipse-Entwickler darauf hinweisen?


----------



## RaoulDuke (10. Jul 2006)

Hehe, wenns wegen falscher Formatierung nicht übersetzt würde, dann wäre da wohl etwas mehr faul. Sieht einfach nach einem kleinen Bug aus, Netbeans formatiert es scheinbar richtig:


```
static void dreiN(int n) {
        if (n<5) return;
        int m = n;
        while (true) {
            while ((m&1) == 0)
                m >>= 1;
            System.out.println(m);
            if (m<n) return;
            m = (3*m+1)>>1;
        }
    }
```

Vielleicht mal auf die entsprechende Mailingliste von Eclipse schreiben?


----------



## PyroPi (10. Jul 2006)

Also mein Eclipse (ver 3.1.0) rückt es richtig ein:


```
public class DreiN {
	static void dreiN(int n) {
		if (n < 5) return;
		int m = n;
		while (true) {
			while ((m & 1) == 0)
				m >>= 1;
			System.out.println(m);
			if (m < n) return;
			m = (3 * m + 1) >> 1;
		}
	}

	public static void main(String[] args) {
		dreiN(27);
	}
}
```


----------



## byte (10. Jul 2006)

> allerdings wird das Programm korrekt übersetzt.



Das hat ja auch nichts mit der Formatierung zu tun. Wenn Du lustig bist, kannst Du auch alles in eine Zeile schreiben. :roll:

Laut Code Convention sollte man die Klammern übrigens immer setzen.


----------



## Leroy42 (11. Jul 2006)

byto hat gesagt.:
			
		

> Laut Code Convention sollte man die Klammern übrigens immer setzen.



Daran werde ich mich genausowenig gewöhnen, wie an die Schnapsidee
von Kernighan/Richie daß *auf einmal jede Anweisung* mit einem Semikolon
beendet werden muß. Vorher war das Semikolon einfach nur ein Trennzeichen
*zwischen* Anweisungen.

Aber ich glaube Wirth war schuld, da er diese sinnlose _Leeranweisung_
eingeführt hatte, und das nur, um der Schluderigkeit vieler Programmierer
entgegenzukommen.  :x


----------



## SamHotte (11. Jul 2006)

Ohne Semikolon zwischen den Anweisungen bekommst du Probleme bei verschachtelten if..else-Konstrukten, daher wurde das eingeführt.


----------



## Leroy42 (11. Jul 2006)

Du meinst sicherlich das _dangling-else_ Problem. 
Das hat aber nichts mit dem Semikolon zu tun.



> Eine der Mehrdeutigkeiten, die in fast allen blockstrukturierten Programmiersprachen auftauchen können, wurde _auch von den Java-Entwicklern *nicht* beseitigt_.



Das Semikolon war bis einschließlich Algol68 das Trennzeichen für Anweisungen
und nichts mehr. Es war also nicht möglich zu schreiben:


```
begin
  a(42);
  b(42);
end
```
weil hinter der Anweisung b(42) und dem schließenden _end_ keine Anweisung folgte.
Deshalb *mußte* es heißen:

```
begin
  a(42);
  b(42)
end
```

Erst Niklaus Wirth (der ja mit im Team der Entwickler von Algol68 war) führte
in Pascal die Leeranweisung ein. Dadurch wurde der erste Block syntaktisch korrekt, da
das Semikolon hinter b(42) einfach diese Anweisung von der folgenden Leeranweisung
trennte.

Gefrustete Mitprogrammierer hatten öfter von mir verlangt, hinter *jeder Anweisung*
ein Semikolon zu setzen um bei Änderung meines Codes nicht von Compilerfehlern überhäuft
zu werden. Allerdings habe ich mich strikt geweigert, unnötige Leeranweisungen in meinen
Code einzubauen.  :bae: 

In Pascal (Delphi, ...) ist der zweite Block auch heute noch legal.

In C wurde schließlich definiert, das das Semikolon kein Trennzeichen mehr ist,
sondern *immer* eine Anweisung abschließt (Ausnahmen: Block- und Leeranweisung).


----------



## Murray (11. Jul 2006)

Leroy42 hat gesagt.:
			
		

> Gefrustete Mitprogrammierer hatten öfter von mir verlangt, hinter *jeder Anweisung*
> ein Semikolon zu setzen um bei Änderung meines Codes nicht von Compilerfehlern überhäuft
> zu werden. Allerdings habe ich mich strikt geweigert, unnötige Leeranweisungen in meinen
> Code einzubauen.  :bae:



Die Ansicht hat sich wohl auch bei Sun durchgesetzt: die folgende Klasse

```
public class Test {

	public static int i() {
		return 1;; //--- zwei Semikola!!
	}
}
```

konnte man mit dem JDK 1.3 noch übersetzen; mit dem JDK 1.5 (und auch mit der  1.6 beta) gibt es einen Fehler:


			
				javac 1.5.0_06 hat gesagt.:
			
		

> C:\home\work\060611>javac Test.java
> Test.java:4: unreachable statement
> return 1;; //--- zwei Semikola!!
> ^
> 1 error



Allerdings ist auch mit dem JDK 1.3 der generierte Bytecode unabhängig davon, ob hier ein oder zwei Semikola stehen; dort wird also offensichlich auch erkannt, dass das zweite Semikolon überflüssig ist; eine Leeranweisung im Sinne eines NOP-Befehls (der ja CPU-Zeit kostet, ohne etwas zu tun) wird also nicht erzeugt


----------

