Tulis C / C ++ Polyglot


27

Konsep tantangan ini cukup sederhana. Yang harus Anda lakukan adalah menulis program yang akan dikompilasi sebagai C yang valid dan C ++ yang valid! Ya, ada beberapa tangkapan. Program harus berperilaku berbeda saat dikompilasi dalam setiap bahasa. Program harus memiliki keluaran yang berbeda untuk setiap bahasa agar dianggap "berperilaku berbeda".

Aturan

  • Program harus C dan C ++ yang valid
  • Program harus memiliki keluaran yang berbeda berdasarkan bahasa yang dikompilasi.
  • #ifdef __cplusplusatau trik preprosesor "mudah" lainnya tidak disarankan! (Namun, operasi preprosesor lainnya baik-baik saja.)
  • Cobalah untuk tidak membuatnya terlihat jelas bahwa program melakukan sesuatu yang berbeda.

Ini adalah , jadi siapa pun yang memiliki solusi paling menarik dan mengejutkan akan menang. Selamat bersenang-senang!

Contoh:

Saya membuat program saya sendiri untuk melihat apakah ini bahkan mungkin dilakukan dengan #ifdeftrik:

#include <stdio.h>
#include <string.h>

char *m="C++ rules!";

int t[11]={0,0,0,0,1,-1,-3,9,-8,82,0};

char tr(char c,int i)
{
    return c+((sizeof('!')+1)&1)*t[i];
}

int main()
{
    int i = 0;
    for(;i<strlen(m);i++)
    {
        printf("%c",tr(m[i],i));
    }
    printf("\n");
    return 0;
}

Output program ini C++ rules!ketika dikompilasi dalam C ++ dan C++ stinksketika dikompilasi dalam C.

Penjelasan:

Apa yang menyebabkan perbedaan antar bahasa adalah tr()fungsinya. Itu mengambil keuntungan dari salah satu perbedaan antara C dan C ++, khususnya, bagaimana literal char diperlakukan. Dalam C, mereka diperlakukan sebagai bilangan bulat, jadi sizeof('!')mengembalikan 4, yang bertentangan dengan 1 di C ++. Bagian ((...+1)&1)ini hanya bagian dari operasi bitwise sederhana yang akan mengembalikan 1 jika sizeof('!')mengembalikan 4, dan 0 jika mengembalikan 1. Angka yang dihasilkan dikalikan dengan int dalam array tdan kemudian produk itu akhirnya ditambahkan ke karakter spesifik yang sedang diubah. Dalam C ++ produk akan selalu nol, sehingga string C++ rules!tetap tidak berubah. Dalam C, produk akan selalu menjadi nilai t, dan string berubah menjadi C++ stinks.


5
Saya yakin ini adalah penipuan sesuatu ...
Beta Decay

@ BetaDecay Benarkah? Saya mencoba mencari sesuatu yang serupa dan saya tidak dapat menemukan apa pun.
Mewy

Bisakah Anda jelaskan bagaimana program Anda bekerja secara berbeda (jika tidak merusak tantangan)?
AL

@AL Saya mengedit penjelasan untuk posting saya.
Mewy

Semua yang dari stackoverflow.com/questions/2038200/… dapat digunakan di sini - dengan sedikit kebingungan.
Jerry Jeremiah

Jawaban:


18

Apakah kue itu bohong?

Karena ada banyak perdebatan tentang apakah kue itu bohong atau tidak, saya menulis program ini untuk menjawab pertanyaan yang kontroversial ini.

#include <stdio.h>

// checks if two things are equal
#define EQUALS(a,b) (sizeof(a)==sizeof(b)) 

struct Cake{int Pie;}; // the cake is a pie!
typedef struct Cake Lie;
main(){
    struct CakeBox{
        struct Cake{ // the cake contains lies!
            Lie Lies[2];
        };
    };
    typedef struct Cake Cake;

    printf("The cake is ");
    if(EQUALS(Cake, Lie)){
        printf("a LIE!\n");
    }else{
        printf("..not a lie?\n");
    }
    return 0;
}

Apa hasilnya nanti?

C:

The cake is ..not a lie?

C ++:

The cake is a LIE!


1
Ini. Saya suka ini.
FUZxxl

9

Hanya beberapa bools

#include <stdio.h>

int test(bool)
  {
  return sizeof(bool) == sizeof(int);
  }

int main(void)
  {
  puts(test(0) ? "C" : "C++");
  return 0;
  }

http://codepad.org/dPFou20W
http://codepad.org/Ko6K2JBH


bool bukan bagian dari C89
malat

8
@malat Yap, dan sebenarnya fakta ini digunakan dalam solusi ini. Untuk c ++ fungsinya adalah tes int (bool / * argumen boolean tanpa nama * /); dan untuk C menggunakan deklarasi int default yang berarti pengujian int (int bool); jadi 'bool' adalah nama variabel integer.
Qwertiy

5

Saya bisa melakukan ini dengan program 3 baris tetapi kemudian akan menjadi jelas mengapa menghasilkan hasil yang berbeda untuk C dan C ++. Jadi alih-alih saya mulai menulis program yang lebih besar dengan beberapa stegonografi yang mendapat hasil berbeda dalam C dan C ++ ...

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

struct product
{
    int quantity;
    char name[20];
    char desc[80];
}; 

struct _customer
{
    char name[80];
    struct product *products;
} customer;

int main(int argc, char *argv[])
{

struct shipment
{
    char tracking_number[40];
    int quantity;
    struct product { int model; int serial; } sku;
};

struct _supplier
{
    char name[80];
    struct shipment *shipments;
} supplier;

/* now read the command line and allocate all the space we need */

if(argc<5)
{
    printf("Usage: %s <supplier name> <# of shipments> <customer name> <# of products> ",argv[0]);
    exit(1);
}

strcpy(supplier.name,argv[1]);
int shipments_size = atoi(argv[2])*sizeof(struct shipment);
printf("Allocating %d bytes for %s shipments\n", shipments_size,supplier.name);
supplier.shipments=(struct shipment *)malloc(shipments_size);

strcpy(customer.name,argv[3]);
int products_size = atoi(argv[4])*sizeof(struct product);
printf("Allocating %d bytes for %s products\n", products_size,customer.name);

/* ... TODO ... finish the rest of this program later */

free(customer.products);
free(supplier.shipments);

return 0;
}

Anda perlu menentukan baris perintah. Ketika saya menjalankannya pada salinan gcc saya, saya mendapatkan hasil ini:

>g++ x.cpp

>a.exe "Bob Supplier" 1 "Jane Customer" 1
Allocating 52 bytes for Bob Supplier shipments
Allocating 104 bytes for Jane Customer products

>gcc x.c

>a.exe "Bob Supplier" 1 "Jane Customer" 1
Allocating 52 bytes for Bob Supplier shipments
Allocating 8 bytes for Jane Customer products

Bagaimana hal-hal buruk bisa terjadi?


Meskipun orang lain melakukan hal yang sama, Anda menutupinya dengan cukup baik.
kirbyfan64sos

5
#include <stdio.h>

int c[1]; 
int main() { 
   struct c { int cpp[2]; }; 
   printf("%d\n", (int)sizeof(c)/4);
}

4

Yang ini bekerja dengan C ++ 11 dan yang lebih baru dan C apa pun sejauh ini (sebelum C11).

#include <stdio.h>

int main()
{
    auto a = 'a';
    printf(sizeof(a) == sizeof(int) ? "C\n" : "C++\n");
    return 0;
}

Lihat di sini: C ++: http://ideone.com/9Gkg75 dan C: http://ideone.com/eECSmr

Itu mengeksploitasi fakta bahwa dalam C ++ 11 kata kunci otomatis mendapat makna baru. Jadi, sementara di C adalah tipe int disimpan di lokasi OTOMATIS itu adalah tipe char di C ++ 11.

EDIT: Seperti yang dikatakan FUZxxl int implisit telah dihapus di C11.


1
Tidak berfungsi dengan C11 karena C11 telah menghapus intaturan implisit .
FUZxxl

@ FuZxxl Terima kasih, saya menyesuaikan posting saya.
Felix Bytow

1

Program yang menggambarkan diri sendiri

Ini akan mencetak "Program ini ditulis dalam bahasa C!" jika dikompilasi menggunakan kompiler C; jika tidak, itu akan mencetak "Program ini ditulis dalam C ++!". Perlu kompiler C99.

#include <stdbool.h>
#include <stdio.h>
char str[] = "This program is written in C++ ";
#define S (sizeof(str)-sizeof(true)-sizeof(true)%4)
int main(){for(int i=S;i<=S+1;++i)str[i]=i==S?'!':'\0';puts(str);return 0;}

Sebagian besar posting lain memanfaatkan perbedaan ukuran char di C vs C ++; ini menggunakan fakta bahwa, dalam C99, truedidefinisikan sebagai angka. Ini memasukkan tanda seru dan terminator nol berdasarkan ukuran true.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.