Plattformübergreifend ... Sie wünschen

8

Schreiben Sie ein Programm, das auf so vielen verschiedenen Plattformen wie möglich unterschiedliche Verhaltensweisen erzeugt. Jede unterschiedliche Plattform vergibt einen Punkt (einschließlich einer anfänglichen Plattform, was bedeutet, dass Sie nicht weniger als 1 * erzielen können). Mechanismen zur Bestimmung der Ziel- / Ausführungsplattform (z. B. durch Plattformkompilierungsanweisungen oder APIs wie .NETs Environment.OSVersion.Platform) dürfen nicht verwendet werden. Die Antwort mit der höchsten Punktzahl gewinnt (wobei Upvotes die Tiebreaker sind).

Betrachten Sie beispielsweise das folgende Programm in der Blub-Sprache : print (1+2). Wenn dieses Programm 3auf jeder Plattform gedruckt würde, auf der es kompiliert und ausgeführt wird, wäre seine Punktzahl 1. Wenn es jedoch aus irgendeinem Grund 4auf PDP-11 drucken würde, wäre seine Punktzahl 2. usw. Aber das Folgende Ein C-Snippet ist beispielsweise ein ungültiger Eintrag : #ifdef WIN32 ... #endif.


Definitionen / Details:

  • Unterschiedliche Plattform: Die Kombination von a) der Hardwarearchitektur b) dem Betriebssystem und seiner Hauptversionsnummer (z. B. 1.0.0 und 1.1.0 gelten als dasselbe Betriebssystem)

  • Unterschiedliches Verhalten: Zwei Verhaltensweisen sind gleich, wenn sie ähnliche Nebenwirkungen hervorrufen (z. B. das Erstellen derselben Datei mit demselben Inhalt) oder wenn es sich bei den Nebenwirkungen um Fehler derselben Art handelt. Wenn ein Programm beispielsweise auf zwei verschiedenen Plattformen segfault, die Meldung segfault auf diesen Plattformen jedoch unterschiedlich ist, wird dies immer noch als dasselbe Verhalten angesehen. Während ein Programm, das auf einer Plattform einen Nullteilungsfehler und auf einer anderen Plattform einen Stapelüberlauf (siehe, was ich dort gemacht habe?) erzeugt, ein anderes Verhalten erzeugt.

  • Alle undefinierten Verhaltensweisen werden als gleichwertig angesehen.

  • Das Programm muss auf allen Plattformen gleichwertig aufgerufen werden (dies bedeutet jedoch, dass Sie Befehlszeilenparameter übergeben können, wenn Sie dies wünschen).


* Nun, ich denke, Sie würden null Punkte erzielen, wenn Ihr Programm auf null Plattformen ausgeführt würde. Aber ähm ... Ja, egal.

Jwosty
quelle
3
Muss das Programm auf allen Plattformen in derselben Programmiersprache ausgeführt werden? Was ist beispielsweise, wenn ich ein Programm schreibe, das 1unter Windows und 2OSX gedruckt wird , mit dem Detail, dass ich es als Python-Skript unter Windows und als C-Programm unter OSX ausführe?
Lynn
1
@ Mauris ja, das Programm muss in derselben Sprache ausgeführt werden. Wenn Sie sich das vorstellen, sollten sie im Allgemeinen dieselben Befehlszeilenparameter (falls vorhanden) verwenden, damit Sie nicht einfach unterschiedliche Argumente auf verschiedenen Plattformen angeben können. Vielen Dank für die großen
Eckfälle
1
Zählen unterschiedliche Browser als unterschiedliche Plattformen für JavaScript?
Downgoat
4
"unterschiedliches Verhalten" erfordert möglicherweise eine genauere Definition. Wenn beispielsweise ein Programm auf mehreren Plattformen abstürzt, jedoch mit unterschiedlichen Fehlern, ist das ein unterschiedliches Verhalten?
Reto Koradi
1
@ mbomb007 Ich bin sicher, dass es eine Million APIs gibt, von denen dokumentiert ist, dass sie sich auf verschiedenen Plattformen unterschiedlich verhalten (was meiner Meinung nach die meisten Lösungen nutzen werden), daher sollten Antworten nicht zu schwer zu überprüfen sein. Was die Bugs betrifft, werden wir diese Brücke verbrennen, wenn wir dazu kommen.
Jwosty

Antworten:

7

C.

Ich werde es mit einem lehrbuchartigen Beispiel versuchen:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char a[] = {1,2,3,4,5,6,7,8};
    if (sizeof(&a) > sizeof(int)) {
        printf("foo %d %d\n", *(int *)a, *(long *)a);
    } else {
        printf("bar %d %d\n", *(int *)a, *(long *)a);
    }
}

64-Bit-Plattformdrucke: foo

32-Bit-Plattformdrucke: Balken

Little Endian Platforms: 67305985

Big Endian-Plattformen: 16909060

Es gibt also mindestens 4 Kombinationen.

Darüber hinaus haben einige sehr alte Plattformen int16-Bit definiert. Und einige Plattformen haben longals 64-Bit definiert. Das Ergebnis wird also auch anders sein.

C war ziemlich plattformspezifisch, wenn Sie tief genug graben. Es ist nicht schwer, Tausende von Kombinationen zu finden (2 ^ 10 +).

einige Benutzer
quelle
3
Liegt das nicht an den \nvs \n\ron * nix und Windows?
Maltysen
Ich denke, das stimmt, wenn ich die Ausgabe unter Linux in eine Datei umlenke und unter Windows lese. Aber ich habe keinen Windows C-Compiler, der dies nativ bestätigt.
einige Benutzer
2
printf("\n");gibt \r\nunter Windows aus (das Umleiten von stdout in eine Datei unter Windows führte zu einer 2-Byte-Datei).
Es1024
3

16/32/64-Bit x86 / x64-Assembly, 16 Byte, 4 Kombinationen

Bytecode:

31 C9 41 E2 0A 66 49 41 74 05 0F 00 C0 03 C1 C3

Demontage (16-Bit):

    xor  cx, cx ;cx=0
    inc  cx     ;cx=1
    loop l1     ;fall through
    dec  cx     ;cx=FFFF
    inc  ecx    ;cx=0000
    je   l1     ;branch taken
    ;...
l1: ret

Demontage (32-Bit):

    xor  ecx, ecx ;ecx=0
    inc  ecx      ;ecx=1
    loop l1       ;fall through
    dec  cx       ;ecx=0000FFFF
    inc  ecx      ;ecx=00010000
    je   l1       ;branch not taken
    sldt ax       ;detect VMware, VirtualPC, Parallels, etc.
    add  ecx, eax ;conditionally modify ecx
l1: ret

Demontage (64-Bit):

    xor   ecx, ecx ;rcx=0 (implicit 64-bit zero-extension)
    loopq l1       ;rcx becomes FFFFFFFFFFFFFFFF, branch taken
    ...
l1: ret

Es gibt
Folgendes zurück: - CX = 0000 im 16-Bit-Modus;
- ECX = 10000 im nicht virtuellen 32-Bit-Modus;
- ECX = (zufällig) im virtuellen 32-Bit-Modus;
- RCX = FFFFFFFFFFFFFFFF im 64-Bit-Modus.

Peter Ferrie
quelle