Lintas platform ... Anda berharap

8

Tulis sebuah program yang akan menghasilkan perilaku yang berbeda pada sebanyak mungkin platform yang berbeda. Setiap platform yang berbeda memberikan satu poin (termasuk platform awal, yang berarti Anda tidak bisa mendapat skor kurang dari 1 *). Mekanisme yang dimaksudkan untuk menentukan target / menjalankan platform (mis. Melalui pernyataan kompilasi platform atau API seperti .NET's Environment.OSVersion.Platform) tidak boleh digunakan. Jawaban dengan skor tertinggi menang (di mana upvote adalah tiebreak).

Sebagai contoh, perhatikan program berikut dalam bahasa Blub: print (1+2). Jika program ini mencetak 3pada setiap platform yang dikompilasi dan dijalankannya, nilainya akan menjadi 1. Namun, jika, karena alasan apa pun, itu akan dicetak 4pada PDP-11, nilainya adalah 2. Dll. Tetapi berikut ini C potongan, misalnya, adalah entri yang tidak valid: #ifdef WIN32 ... #endif.


Definisi / perincian:

  • Platform yang berbeda: kombinasi a) arsitektur perangkat keras b) OS dan nomor versi MAJOR-nya (mis. 1.0.0 dan 1.1.0 dianggap sebagai OS yang sama)

  • Perilaku yang berbeda: dua perilaku adalah sama jika mereka menghasilkan efek samping yang sama (misalnya membuat file yang sama dengan konten yang sama), atau jika efek sampingnya adalah kesalahan dari jenis yang sama. Sebagai contoh, jika suatu program segfault pada dua platform yang berbeda, tetapi pesan segfault berbeda pada platform ini, ini masih dianggap perilaku yang sama; sementara program yang menghasilkan kesalahan nol-divisi pada satu platform dan stack overflow (lihat apa yang saya lakukan di sana?;) kesalahan pada yang lain menghasilkan perilaku yang berbeda.

  • Semua perilaku tidak terdefinisi dianggap setara.

  • Program harus dijalankan dengan cara yang setara pada semua platform (namun; ini berarti Anda dapat melewati parameter baris perintah jika diinginkan)


* Ya, saya kira Anda akan mendapat skor nol jika program Anda berjalan pada platform nol. Tapi um ... Ya tidak pernah.

Jwosty
sumber
3
Haruskah program dijalankan dalam bahasa pemrograman yang sama di semua platform? misalnya bagaimana jika saya menulis program yang mencetak 1pada Windows dan 2OSX, dengan detail yang saya jalankan sebagai skrip Python pada Windows dan program C pada OSX?
Lynn
1
@Mauris ya, program harus dijalankan dalam bahasa yang sama. Juga, kalau dipikir-pikir itu, mereka umumnya harus mengambil parameter baris perintah yang sama (jika ada), sehingga Anda tidak bisa hanya memberikan argumen yang berbeda pada platform yang berbeda. Terima kasih untuk kasus-kasus sudut yang hebat sejauh ini :)
Jwosty
1
Apakah browser yang berbeda dianggap sebagai platform yang berbeda untuk JavaScript?
Downgoat
4
"perilaku yang berbeda" mungkin memerlukan definisi yang lebih tepat. Misalnya, jika sebuah program mogok di beberapa platform, tetapi dengan kesalahan yang berbeda, apakah itu perilaku yang berbeda?
Reto Koradi
1
@ mbomb007 Saya yakin ada sejuta API yang didokumentasikan untuk berperilaku berbeda pada platform yang berbeda (yang saya harapkan sebagian besar solusi akan mengambil keuntungan dari), jadi jawaban seharusnya tidak terlalu sulit untuk diverifikasi. Adapun yang bug, yah, kita akan membakar jembatan itu ketika kita sampai di sana.
Jwosty

Jawaban:

7

C

Saya akan menikamnya dengan contoh seperti buku teks:

#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);
    }
}

Cetakan Platform 64-bit: foo

Cetakan Platform 32-bit: bilah

Platform Little Endian: 67305985

Platform Big Endian: 16909060

Jadi setidaknya ada 4 kombinasi.

Selain itu, beberapa platform yang sangat lama telah intdidefinisikan sebagai 16-bit. Dan beberapa platform telah longdidefinisikan sebagai 64-bit. Jadi hasilnya akan berbeda juga.

C sudah cukup spesifik untuk platform, jika Anda menggali cukup dalam. Tidak sulit menghasilkan ribuan kombinasi (2 ^ 10+).

beberapa pengguna
sumber
3
Bukankah ini empat karena \nvs \n\rpada * nix dan windows?
Maltysen
Saya kira itu benar jika saya mengalihkan output ke file di Linux dan membacanya di Windows. Tapi saya tidak punya kompiler Windows C untuk mengkonfirmasi itu secara asli.
beberapa pengguna
2
printf("\n");tidak output \r\npada windows (mengarahkan stdout ke file di windows menghasilkan file 2 byte).
es1024
3

Perakitan x86 / x64 16/32/64-bit, 16 byte, 4 kombinasi

Kode byte:

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

Pembongkaran (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

Pembongkaran (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

Pembongkaran (64-bit):

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

Ia mengembalikan:
- CX = 0000 dalam mode 16-bit;
- ECX = 10000 dalam mode non-virtual 32-bit;
- ECX = (acak) dalam mode virtual 32-bit;
- RCX = FFFFFFFFFFFFFFFFFF dalam mode 64-bit.

Peter Ferrie
sumber