Концепція цього виклику досить проста. Все, що вам потрібно зробити - це написати програму, яка буде компілювати як дійсні 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++ stinks
при компіляції в C.
Пояснення:
Що викликає різницю між мовами - це
tr()
функція. Скористається однією з відмінностей між C і C ++, зокрема, способом поводження з літерами char. У C вони розглядаються як цілі числа, томуsizeof('!')
повертає 4, на відміну від 1 у C ++.((...+1)&1)
Частина є лише частиною простий операції побітового , який буде повертати 1 , якщоsizeof('!')
повертає 4, і 0 , якщо вона повертає 1. Це в результаті чого число множиться на цілих чисел в масиві ,t
а потім , що продукт , нарешті , додають до специфічний характер трансформується. У C ++ продукт завжди буде нульовим, тому рядокC++ rules!
залишається незмінною. У C продукт завжди буде значенням уt
, і тому рядок змінюється наC++ stinks
.