Seite 1 von 2

[Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:16
von zwergmulch
Hallo, ich beginn hier mal ein kleines Ratespiel. 8-)
Postet bitte verwirrende Code-Fragmente und lasst die anderen (vlt. ca. 24h) raten was die ausgeben.
Ausführen verboten! ;)

Ich fange dann gleich mal an:
*beim rumstöbern hier gefunden*
Das ganze ist in Java und nutzt Reflection.
Da sage noch einer das Java harmlos ist... :D

Code: Alles auswählen


import java.lang.reflect.Field;

public class Test {

    public static void main(String[] args) {
        System.out.print("Hallo");
        System.out.println(" Welt");
    }

    static {
        try {
            Field field = String.class.getDeclaredField("value");
            field.setAccessible(true);
            Object blupp = new char[]{'A', 'd', 'i', 'o', 's'};
            System.arraycopy(blupp, 0, field.get("Hallo"), 0, 5);
        } catch (Exception ex) {
        }
    }
}

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:23
von Aramis
Adios Welt
:-)

Ist wirklich garantiert dass zwei gleiche Stringliterale in einer Uebersetzungseinheit auf das gleiche Objekt verweisen? Oder ist das die Entscheidung des Compilers?

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:25
von zwergmulch
Ja, ist garantiert. Strings sind in Java immutable und werden in einem String-Pool gespeichert.
Das heißt, das wenn man 2 Strings "Hallo" hat, die beide die gleiche Adresse haben.
Ist ganz witzig obwohl man sowas ja eigentlich nicht machen sollte... :D

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:29
von Psycho
Ich fand ihn hier immer beeindruckend:

Code: Alles auswählen

 #define _ -F<00||--F-OO--;
 int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
 {
             _-_-_-_
        _-_-_-_-_-_-_-_-_
     _-_-_-_-_-_-_-_-_-_-_-_
   _-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
   _-_-_-_-_-_-_-_-_-_-_-_-_-_
     _-_-_-_-_-_-_-_-_-_-_-_
         _-_-_-_-_-_-_-_
             _-_-_-_
 }

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:35
von zwergmulch
Und die Antwort ist... PI! Wirklich witzig :D

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:36
von Aramis
Diesmal C. Ein gutes Argument gegen ‘...’.

Code: Alles auswählen

void foo(int i,...) {
	va_list argptr;
        va_start(argptr, i);

	printf("%f", va_arg(argptr,float));
}

int main()
{
	foo(4,3.1415926f);
}

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:39
von zwergmulch
Tut mir leid, kann mich einfach nicht zurückhalten ;-)
Die Antwort ist 3.1415926
Ist hier einer im PI-Club ? :D

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:40
von Aramis
Leider falsche Antwort :-)

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:44
von zwergmulch
Mist! Aber müsste die Funktion nicht

Code: Alles auswählen

void foo(int i ...)
lauten?
Außerdem hast du "va_end" vergessen. Böse! (macht zwar in diesem Fall nichts, aber egal) :D

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:48
von Aramis
Ich hab es bewusst weggelassen. Es aendert an der einzigen richtigen Antwort nichts :-)

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:50
von jgl
4?

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:52
von zwergmulch
Nein, 2.000000. - Wirklich trickreich 8-) 8-) 8-) 8-)

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:53
von Aramis
jgl: leider nein :-)
zwergmulch: das hast du ausprobiert :-) Auch die Antwort ist aber falsch, außer du kannst sie begruenden :-)

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:59
von Alexander Kornrumpf
Liegts an printf bzw. hätte diese Version dasselbe Problem?

Code: Alles auswählen

void foo(int i,...) {
        va_list argptr;
        va_start(argptr, i);
        float val = va_arg(argptr,float);
        printf("%f", val);
}

int main()
{
        foo(4,3.1415926f);
}

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 14:59
von Aramis
Ebenfalls nicht :-)

Alex 1, deine Version sollte das gleiche Problem haben.

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:02
von zwergmulch
OK, ich geb's zu. Aber wie ist nun die Lösung??? [neugierig]*Erklärung haben wollen*[/neugierig] :?:

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:04
von jgl
Ich sage 4 mal 3.14.... *unruhig auf seinem Stuhl sitzend*
NEIN, oder doch nicht....

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:06
von Alexander Kornrumpf
Psycho hat geschrieben:Ich fand ihn hier immer beeindruckend:
[blubb]
Was ich dabei nicht verstehe, warum der präprozessor nicht den underscore zwische F und OO beim Funktionsnamen ersetzt.

EDIT:
Macht man sich normal keine Gedanken drüber: ist -- ein anderes Token ist als - - (letzteres eigentlich zwei Token)? Slightly related: Kompiliert int i=1; ---i; und wenn ja zu was?

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:12
von Aramis
Nagut, die Aufloesung (*duckt sich praeventiv weil er sich nicht ganz an die Regeln gehalten hat*):

Undefined Behaviour.

floats werden bei Uebergabe an eine variable Argumentliste nach double konvertiert. Das ist auch der Grund weshalb printf's ‘%f’ fuer beide, float und double, funktioniert. In der Praxis ist das Ergebnis gemaess IEEE 754 durchaus vorhersagbar.

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:15
von Psycho
Alexander Kornrumpf hat geschrieben:
Psycho hat geschrieben:Ich fand ihn hier immer beeindruckend:
[blubb]
Was ich dabei nicht verstehe, warum der präprozessor nicht den underscore zwische F und OO beim Funktionsnamen ersetzt.
http://msdn.microsoft.com/en-us/library ... S.80).aspx
The identifier is replaced only when it forms a token. (See C++ Tokens in the C++ Language Reference.) For instance, identifier is not replaced if it appears in a comment, within a string, or as part of a longer identifier.
Edit: Oh zu langsam.
Slightly related: Kompiliert int i=1; ---i; und wenn ja zu was?
http://msdn.microsoft.com/en-us/library ... S.80).aspx
The parser separates tokens from the input stream by creating the longest token possible using the input characters in a left-to-right scan. Consider this code fragment:

a = i+++j;
The programmer who wrote the code might have intended either of these two statements:

a = i + (++j)

a = (i++) + j
Because the parser creates the longest token possible from the input stream, it chooses the second interpretation, making the tokens i++, +, and j.

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:16
von jgl
/Toller Thread :) [/i]

*Gesicht zum Fragezeichen geballt*

Wieso lässt sich das vorhersagen?
Wieso kommt da 2.0000 heraus?

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:27
von Aramis
Naja, weil du das Bitmuster des double's, den der Aufrufer auf den Stack schiebt, halbwegs vorhersagen kannst. Und dann schneidet die Funktion ja quasi die untere Haelfte davon weg und interpretiert sie als float :-)

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.05.2010, 15:29
von jgl
Ahh, okay!
Danke für die Erklärung :)

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 12.05.2010, 07:34
von Lord Delvin
Macht das jeder Compiler? Kann mich an so Probleme nicht erinnern, obwohl ich mal relativ begeistert varargs verwendet hab. Is aber mit variablen Templateargumenten total nutzlos geworden.

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 12.05.2010, 11:43
von Aramis
Naja, der C++11–Draft spezifiziert das Verhalten, C99 auch. Leider etwas verklausuliert:
C++11/n3092 5.2.2.7 hat geschrieben: When there is no parameter for a given argument, the argument is passed in such a way that the receiving
function can obtain the value of the argument by invoking va_arg



After these conversions,if the argument does not have arithmetic, enumeration, pointer, pointer to member, or class type, the program is ill-formed. Passing a potentially-evaluated argument of class type (Clause 9) with a non-trivial copy constructor or a non-trivial destructor with no corresponding parameter is conditionally-supported, with implementation-defined semantics. If the argument has integral or enumeration type that is subject to the integral promotions (4.5), or a floating point type that is subject to the floating point promotion (4.6), the value of the argument is converted to the promoted type before the call. These promotions are referred to as the default argument promotions
So, naechstes Raetsel. Legt los :-)

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 16.05.2010, 15:59
von zwergmulch
Dann will ich mal das nächste anfangen.

Das Ganze ist in Scala, gefunden habe ich das bei
Bitte nicht gucken - nur eine Quellen-AngabeIT-Republik/JAXENTER
Wollen wir mal anfangen! Das ist eine Art "Bibliothek", die die nachfolgende Applikation nutzt:

Code: Alles auswählen

import scala.actors._

trait StoppableActor extends Actor {
  private var handler: Any => Any = {null}

  def act {
    while (true) {
      receive {
        case "STOP" => println ("stop"); exit (null)
        case o => handler (o)
      }
    }
  }
  
  def handle (f: Any => Any) = handler = f
}

object StoppableActor {
  def run (f: Any => Any) = {
    new StoppableActor {
      handle (f)
    }.start
  }
}
Nun die wirkliche Applikation:

Code: Alles auswählen

import StoppableActor._
object Main extends Application {
val stage1 = run {
  case i: Int if i > 0 => stage2 ! i
  case _ => null
}

val stage2 = run { 
  case i: Int => 
    stage3 ! "Die Zahl " + i
    stage3 ! i
}
  
val stage3 = run { 
  case i: Int    => println ("Int:    " + i)
  case o: String => println ("String: " + o)
}
  
stage1 ! 5
stage1 ! -1
  
stage1 ! "STOP"
stage2 ! "STOP"
stage3 ! "STOP"
}
Viel Glück beim Raten!

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 16.05.2010, 19:17
von Hanno
String: Die Zahl 5
Int: 5
stop
stop
stop

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 17.05.2010, 13:52
von zwergmulch
Stimmt. Der nächste, bitte! :D

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 17.05.2010, 14:43
von Zudomon
Huhu,
jetzt von mir, ein Programm, welches ich damals für Microcontroller-Programmierung angefertigt habe...
vielleicht errät ja jemand, wofür das da ist oder wie es funktioniert... dafür müsste es aber eventuell erstmal enthedert werden:

Code: Alles auswählen

#include <io6811.h>
#include <boardio.h>
#include <int6811.h>
unsigned char k[12],x
=0,a[12]={0,64,0,121,36,
48,25,18,2,120,0,16};unsigned
short z=0;interrupt void TOC5_interrupt
(void){TFLG1=8;TOC5=TCNT+2500;PIA1BDR=(x=++x
%12)%4;PIA1ADR=a[z>>(x%4)*4&15];if(!k[x]&&k[x]
=!(PIA1BDR&(32<<x%3)))z=(z<<4)*(x!=9)|(z>>4)*(x
==9)|x*(x!=9);}voidmain (void){PIA1ACR=PIA1BCR=
0;PIA1ADR=127;PIA1BDR=3;PIA1ACR=PIA1BCR=PIA_DR;
TMSK1=8;enable_interrupt();while(1);}
Viel Spass beim raten! :D

Re: [Sammelthread]Verwirrende Code-Fragmente

Verfasst: 11.07.2010, 12:41
von zwergmulch
Ok, wird wohl so schnell keiner mehr erraten, also: "Auflösung bitte!" ;)

Ich fange aber schon mal mit dem nächsten an:
Ist in Java, und weil das sonst zu leicht wäre, habe ich mal die Namen "verschlüsselt":

Code: Alles auswählen

public class Foo<T>{
public boolean m1() { return true; }
public T m2(){ return null; }
public Foo<T> m3 () { return null; }
public Foo<T> m4 (final T bar) {
 final Foo<T> v1 = this;
 return new Foo<T> (){
 public boolean m1 () { return false; }
 public T m2 () { return bar; }
 public Foo<T> m3 () { return v1;}
};
}
}
Na, was implementiert das :?:
Und Zusatzfrage: Bitte eine möglichst gleiche Implementierung in C++ (meiner Meinung nach nicht möglich). :twisted: