Задача

Що побачимо на екрані у результаті виконання наступного коду?

1 int f1(char a, char b) 2 { 3 unsigned char x = (unsigned char)a - (unsigned char)b; 4 return x; 5 } 6 7 int f2(char a, char b) 8 { 9 return (unsigned char)a - (unsigned char)b; 10 } 11 12 ... 13 cout << f1('a', 'b') << ", " << f2('a', 'b') << endl; 14 ...

Рішення

Перша функція перетворює код символа “а” у беззнаковий байт (нехай буде 01100001 у двійковій системі), так само для “b” (01100010). АЛЕ! З метою оптимізації всі арифметичні операції виконуються над цілими числами. Нехай ціле буде 2 байти. Тоді результат віднімання буде дорівнювати –1:

00000000001100001 – 0000000001100010 = 1111111111111111

Далі ціле перетворюється у беззнаковий байт відкиданням старшого байта, тобто отримуємо 11111111. А оскільки функція повертає не байт, а ціле то значення розширюється додаванням нульових байтів. Тобто для першої функції результат буде 0000000011111111, що дорівнює 255.

У другому ж випадку той int що ми отримали в результаті віднімання (1111111111111111) повертається без змін і маємо –1.

Тобто виведено буде “255, –1”.

Спочатку давайте подивимося на код.

template <class T> class Storage { public: virtual void AddValue(T v) = 0; }; template <class T> class ListValues { public: ListValues(Storage<T> &s) : m_s(s) {} ListValues<T> operator,(T v) { m_s.AddValue(v); return *this; } private: ListValues(); Storage<T> &m_s; }; template <class T> class ListWithOverridenComaOperator: public vector<T>, public Storage<T> { public: ListValues<T> operator=(T v) { push_back(v); return ListValues<T>(*this); } virtual void AddValue(T v) { push_back(v); } };

Що тут відбувається? Для нашого контейнера перевизначено оператор присвоювання – він додає елемент у коллекцію і повертає ListValue<T> у якого в свою чергу перевантажено оператор кому.

Тобто подібний запис:

ListWithOverridenComaOperator<double> a; a = 0.1, 0.2, 0.3;

Буде трансформавано у щось на зразок:

a.operator=(0.1).operator,(0.2).operator,(0.3);

Задача

Що побачимо на екрані після виконання наступного коду?

int j = 0; // what will you see??/ for(size_t i = 0; i < 10; ++i) { ++j; } std::cout << j << std::endl;

 

Очикуємо звісно побачити 10, але побачимо 1.

Що відбувається?

Уся справа у тріграфах – http://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C. Послідовність символів ??/ інтерпретується як символ що означає продовження коментаря на наступному рядку. Тому рядок з циклом for буде закоментовано.