C / C ++ Polyglot 작성


27

이 도전의 개념은 매우 간단합니다. 유효한 C와 유효한 C ++로 컴파일 할 프로그램을 작성하기 만하면됩니다! 글쎄, 몇 가지 캐치가 있습니다. 프로그램은 각 언어로 컴파일 될 때 다르게 작동해야합니다. "다르게 동작하는"것으로 간주 되려면 프로그램마다 언어마다 다른 출력이 있어야합니다.

규칙

  • 프로그램은 유효한 C 및 C ++ 여야합니다.
  • 프로그램은 컴파일 된 언어에 따라 다른 출력을 가져야합니다.
  • #ifdef __cplusplus또는 다른 "쉬운"전 처리기 트릭은 권장하지 않습니다! (하지만 다른 전 처리기 작업은 완벽합니다.)
  • 프로그램이 다른 것을한다는 것을 완전히 명백하게 보이도록하지 마십시오.

이것은 이므로 가장 흥미롭고 놀라운 솔루션을 가진 사람이 승리합니다. 즐기세요!

예:

나는 이것이 #ifdef속임수 로도 가능한지 확인하기 위해 내 자신의 프로그램을 만들었습니다 .

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

이 프로그램 C++ rules!은 C ++로 컴파일되고 C로 컴파일 될 때 출력 됩니다 C++ stinks.

설명:

언어의 차이를 일으키는 것은 tr()기능입니다. C와 C ++의 차이점 중 하나, 특히 문자 리터럴을 처리하는 방법을 활용합니다. C에서는 정수로 취급되므로 sizeof('!')C ++에서는 1이 아니라 4를 반환합니다. 이 ((...+1)&1)부분은 간단한 비트 단위 연산 의 일부일뿐입니다. sizeof('!')4를 반환 하면 1을 반환하고 1을 반환하면 0을 반환합니다. 결과 숫자에 배열의 정수를 곱한 다음 결과적 t으로 변환되는 특정 문자에 곱이 추가됩니다. C ++에서 제품은 항상 0이므로 문자열 C++ rules!은 변경되지 않습니다. C에서 제품은 항상의 값 t이므로 문자열은로 바뀝니다 C++ stinks.


5
나는 이것이 무언가의 속임수라고 확신한다 ...
Beta Decay

@BetaDecay 그렇습니까? 비슷한 것을 찾으려고 시도했지만 아무것도 찾지 못했습니다.
Mewy

프로그램이 어떻게 다른 방식으로 작동하는지 설명해 주시겠습니까 (도전을 해치지 않는 경우)?
AL

@AL 게시물에 대한 설명을 편집했습니다.
Mewy

stackoverflow.com/questions/2038200/…의 모든 것을 약간 난독 화로 여기에서 사용할 수 있습니다.
Jerry Jeremiah

답변:


18

케이크가 거짓말입니까?

케이크가 거짓말인지 아닌지에 대해 많은 논쟁이 있었으므로, 나는이 논쟁적인 질문에 답하기 위해이 프로그램을 썼습니다.

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

결과는 무엇입니까?

기음:

The cake is ..not a lie?

C ++ :

The cake is a LIE!


1
이. 나는 이것을 좋아한다.
FUZxxl

9

그냥 부울

#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은 C89의 일부가 아닙니다
malat

8
@malat Yep, 정확히이 사실은이 솔루션에 사용됩니다. C ++의 경우 함수는 int test (bool / * unnamed boolean argument * /); C의 경우 기본 int 선언을 사용합니다. int test (int bool); 따라서 'bool'은 정수 변수의 이름입니다.
Qwertiy

5

3 줄 프로그램 으로이 작업을 수행 할 수 있었지만 C 및 C ++에 대해 다른 결과를 생성하는 이유는 분명합니다. 대신 C와 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;
}

명령 행을 지정해야합니다. gcc 사본에서 실행하면 다음과 같은 결과가 나타납니다.

>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

어떻게 그렇게 끔찍하게 잘못 될 수 있습니까?


다른 사람들도 같은 일을했지만, 당신은 그것을 잘가 렸습니다.
kirbyfan64sos

5
#include <stdio.h>

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

4

이것은 C ++ 11 이상 및 모든 C (C11 이전)에서 작동합니다.

#include <stdio.h>

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

여기를 참조하십시오 : C ++ : http://ideone.com/9Gkg75 및 C : http://ideone.com/eECSmr

그것은 C ++ 11에서 auto 키워드가 새로운 의미를 가지고 있다는 사실을 이용합니다. 따라서 C의 a는 자동 위치에 저장된 int 유형이지만 C ++ 11의 경우 char 유형입니다.

편집 : FUZxxl은 암시 적 int가 C11에서 제거되었다고 말했습니다.


1
C11이 암시 적 int규칙을 제거 했으므로 C11에서는 작동하지 않습니다 .
FUZxxl

@FUZxxl 감사합니다. 게시물을 조정했습니다.
Felix Bytow

1

자기 설명 프로그램

"이 프로그램은 C로 작성되었습니다!"라고 인쇄됩니다. C 컴파일러를 사용하여 컴파일 된 경우; 그렇지 않으면 "이 프로그램은 C ++로 작성되었습니다!"라고 인쇄됩니다. 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;}

대부분의 다른 게시물은 C와 C ++의 문자 크기 차이를 이용합니다. 이것은 C99에서 true숫자로 정의 된다는 사실을 사용합니다 . 크기에 따라 느낌표와 null 종결자가 삽입됩니다 true.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.