Мой вопрос о statement expressions, которые добавлены в качестве расширения в GNU C. Рассмотрим следующий код:Является ли переопределение переменных в выражениях выражений безопасными?
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i = 0;
printf("%d\n", i);
{int i = 1;printf("%d\n", i);}
printf("%d\n", i);
return EXIT_SUCCESS;
}
Компиляция (gcc -Wall -std=gnu99 lala.c -o lala
) и запуск даст:
0
1
0
Эта практика (использование расширения) является довольно обычным явлением, особенно в container_of
в ядре Linux:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) *__mptr = (ptr);
(type *)((char *)__mptr - offsetof(type,member));})
Как и в этом случае, я хочу определить макрос, который объявляет локальную переменную и что-то делает с ней. Однако я хочу сделать это, не загрязняя имена переменных, доступные в текущей области действия, и избегать возможных переопределений. Я не смог найти в документации информацию о том, как точно определяется область видимости в случаях переопределений.
В приведенном выше случае от компилятора не выдается предупреждение о переопределении. Мой вопрос заключается в том, могу ли я полагаться на то, что переменная, ограниченная внутри выражения оператора, не будет влиять на переменную с тем же именем во внешней области?
Что не допускается в объявлении переменных, имена которых начинаются с двух подчеркивания. – dreamlax
Разве ваше использование не просто составное заявление? для того, чтобы оно было выражением оператора, оно должно быть заключено в скобки в соответствии с связанной документацией – msam
@msam: yes, но я хочу определить макрос, используя скобки –