Я заметил, что иногда, C макросы записаны как что-то вроде этого:
#define foo(bar) ({ ++bar; })
После некоторого экспериментирования я нашел что:
({});
скомпилирует, но ничего не сделает. (Как ожидалось.);
прочь вызовет синтаксическую ошибку. Побочный эффект этого гарантирует, что нечто () похоже на функцию в Вашем коде. (Хотя, если Вы оставляете точку с запятой, ошибка не очень полезна для диагностирования проблемы!)return ({});
жалуется на пустое значение, не проигнорированное, точно так же, как если я попытался использовать пустую функцию.Это должно только заставить разработчиков добавить точку с запятой к своим макросам, или они имеют другую цель? Я попробовал Google, но он терпит полный провал с пунктуацией. Существует ли название этого?
.NET поддерживает это с атрибутом [Flags]:
[Flags]
enum KbdHookFlags {
Extended = 0x01,
Injected = 0x10,
AltPressed = 0x20,
Released = 0x80
}
Пример использования:
KBDLLHOOKSTRUCT info = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
if ((info.flags & KbdHookFlags.Released) == KbdHookFlags.Released) {
// Key was released
// etc..
}
-121--4121299- просто «svn copy» отсутствующие папки из ветви для рекурсивного багажника.
-121--3021061-Это расширение GNU, называемое выражениями оператора .
При объявлении макросов в стандарте-C часто появляется do..., в то время как (0)
циклы, используемые для аналогичных целей (т.е. создание области блока). Выражение инструкции превосходит взлом цикла, поскольку оно может возвращать значение. Если вы хотите сделать что-то подобное в стандарте-C, вам придется определить дополнительную функцию и потерять удобство лексического объема.
Прохладная вещь о выражениях операторов (если есть классное), это то, что последнее утверждение является результатом выражения.
#define foo(bar) ({ ++bar; 3.1415927; })
int i = 0;
float pi = foo(i);
() - это выражение. ({код; код;}) - составное утверждение внутри выражения. Это расширение GNU C.
http://gcc.gnu.org/onlinedocs/gccc-2.95.3/gcc_4.html
Редактировать: вау, я получил эту ссылку от Google и не заметил, что она была для GCC 2.95 сначала. Древний!