Программа
x.c
:#include <stdio.h>
int main() {
char s[4];
s[0] = 'C'; s[1] = s[2] = '+'; s[3] = 0;
s[sizeof(' ') ^ 5] = 0;
printf("%s\n", s);
return 0;
}
Компилируем и запускаем.Visual Studio:
cl x.c && x
или в Cygwin:gcc -o x x.c && x
Имеем следующий результат:C
А теперь так:cl /TP x.c && x
или в Cygwin:g++ -o x x.c && x
Теперь программа печает иное:C++
Результат повеселил некоторых моих коллег.Нашел небольшой список еще некоторых "отличий" С и С++, но, пожалуй, этот самый неявный, а значит потенциально опасный.
Прикольно, однако ожидаемо. Стандарт не регламентирует, что просто char будет 1 байт. sizeof(unsigned char) будет 1. Это точно. А просто char запросто может быть равен int.
ОтветитьУдалитьА вот в вашем примере правильнее делать sizeof(s[0]) все-таки.
Да, если изменить на s[0] все будет очевидно. Тут проблема именно в интерпретации символьной константы типа 'a'. В C это int и как результат, например 4, а в С++ это char, то есть стопудово 1.
ОтветитьУдалитьКонечно, мало кто в здравом уме будет писать sizeof('a') без какой-то особой коварной цели, но уж если напишет, то будет долго ловить этот глюк.
2bialix:
ОтветитьУдалитьой ли - таки стандарт не регламентирует sizeof(char) ? Кёрниган и Ричи пишут как раз, о том, что sizeof(char) в Си всегда 1.
sizeof(char) - это всегда 1, а не только sizeof(unsigned char), а вот sizeof('a') - это зависит от С или C++
ОтветитьУдалитьСтандарт не гарантирует значение sizeof(wchar_t), это да.
Не вкурил зачем вы в примере пишете в неинициализированную память?
ОтветитьУдалитьТочнее не в неинициализированную память а за границу стека (см. предыдущий коммент)
ОтветитьУдалитьВ каком именно месте происходит выход на границу стека?
ОтветитьУдалитьСмотрите char s[4]; в и далее s[sizeof(' ') ^ 5] = 0; XOR для С++ дает 4, т.е. запись в 5-й элемент массива, хотя на стеке было выделено 4.
ОтветитьУдалитьФакт. Эх, хотел извернуться как-нибудь оригинально, но в итоге вышло как всегда.
ОтветитьУдалитьНадо было не умничать, а просто написать:
#include <stdio.h>
int main() {
printf(sizeof('a') == 1 ? "C++" : "C");
}