вторник, 23 февраля 2010 г.

Баг в компиляторе?

Сегодня продолжил свой небольшой challenging, посвящённый C++/CLI и вообще C++. Давно было интересно, как получить отдельные элементы из параметров для макросов __VA_ARGS__ (я использовал их вместе с template’ами, очень выразительная штука получается). Загуглил, наткнулся на это обсуждение: http://www.codeguru.com/forum/showthread.php?t=468033

Мужик очень красиво придумал, но создатели стандарта C++ залажали, и его идея не работала до конца. Я решил проверить, как обстоят дела с этой проблемой в C++/CLI, выяснилось, что всё точно так же. Объявляем хитрые макросы, которые (теоретически) помогут нам работать со списком параметров как со списком в Лиспе или любом другом функциональном языке (они позволят нам обращаться к “голове” и “хвосту” любого подсписка списка рекурсивно):

  1. #define EXPAND(a) a
  2. #define H(a, ...) a
  3. #define B(a, ...) __VA_ARGS__
  4. #define FOO(...) H(EXPAND(__VA_ARGS__))
  5. #define BAR(...) B(EXPAND(__VA_ARGS__))

А теперь попробуем использовать:

  1. int fst = FOO(10, 20, 30); // OK, fst == 10.
  2. int sec = FOO(BAR(10, 20, 30)); // Compilation error.
  3. int arr[2] = { BAR(10, 20, 30) }; // Expected arr[0] == 20, arr[1] == 30, but both are null.

Как видим, первый элемент списка возвращается корректно, а вот второй элемент, так же как и “хвост” списка, возвращается некорректно. Такие дела.

Комментариев нет:

Отправить комментарий