What happens if you declare a variable inside a macro?

Suppose I have a macro defined as follows:

#define FOO (x, y) \
do {
  int a, b;
  a = f (x);
  b = g (x);
  y = a + b;
} while (0)

When expanding a macro, does GCC “guarantee” any uniqueness for a, b? I mean, if I use FOO as follows:

int a = 1, b = 2;
FOO (a, b);

After that, the pre-processing will be as follows:

int a = 1, b = 2;
do {
  int a, b;
  a = f (a);
  b = g (b);
  b = a + b;
} while (0)

Can the / compiler distinguish between ado {} and ado? What tricks can I use to guarantee any uniqueness (besides the fact that the variables inside have a distorted name, which is unlikely that someone else will use the same name)?

( , )

+4
9

. , ( , #pragma, ).

a b . . .

int a = 1, b = 2;
do {
  int a___,b___;
  a___ = f(a___);
  b___ = g(b___);
  b___ = a___+b___;
} while (0)

++, . c 1999 , inline c. http://en.wikipedia.org/wiki/Inline_function

c , ():

#define FOO(x,y) \
do {
  int FOO__a,FOO__b;
  FOO__a = f(x);
  FOO__b = g(x);
  y = FOO__a+FOO__b + (y)*(y);
} while (0)

. , (y) * (y),

. :

#define max(a,b) a>b?a:b
max(i++,--y)

, .

+6

, , a, b do..while() , .

, a, b do..while().

, MACRO.

+7

, . C ++ lisp gensym .

+3

a b .

C , , , .

, :

#include <stdio.h>

#define FOO(x) \
{              \
  int a;       \
  a = x;       \
  printf("%d\n", a); \
}


int main()
{
  int a = 1;

  {
    int a = 2;

    printf("%d\n", a); // 2

    FOO(3); // 3

    printf("%d\n", a); // 2
  }

  printf("%d\n", a); // 1

  getchar();
}

, , "" , C , . .

Btw MISRA-C , , , , .

( - . , .)

+3

, .

Infact, - .

.

, , :

#define FOO(x,y) \
do {
  int FOO_MACRO_a, FOO_MACRO_b;
  FOO_MACRO_a = f(x);
  FOO_MACRO_b = g(x);
  y = FOO_MACRO_a + FOO_MACRO_b;
} while (0)
+1

gcc / g++, :

#define max(x, y) ({ typeof(x) a_ = (x); \
                     typeof(y) b_ = (y); \
                     (a_ > b_) ? a_ : b_ })

, .

, . , , gcc/g++, .

: http://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_3.html#SEC30

, gcc/g++ -Wshadow -Wshadow. . -Werror . , . , , . Do/while(), , .

int a;

// code from macro;
do { int a = 5; ... } while(false);

, (-Wshadow + -Werror), , int a = 5.

+1

, , x y, , :

#define FOO(x,y) \
do\
{\
  int x##y##a,x##y##b;\
  x##y##a = f(x);\
  x##y##b = g(x);\
  y = x##y##a + x##y##b;\
} while (0)

, a b x y, , . , , , , .

+1

, , , , - , a a, . "" , . int FOO_a, FOO_b;

0

, , x, l , .

Even if you need a macro, it can still be a light wrapper around the built-in function, and one that takes x and gives you both f(x), and g(x)without having to overestimate x, will certainly be safe.

In your case, something like:

template< typename T >
struct Foo
{
   T& x;

   explicit Foo(T&x_) : x(x_)
   {
   }   

   int f();
   int g();
};

template<typename T>
Foo<T> makeFoo(T& x)
{
     return Foo<T>(x);
}

#define FOO(x,y)
{
   Foo FOO_VAR(x);
   y = FOO_VAR.f() + FOO_VAR.g();
}

will be a safer way to do something. Of course, if you don't need a macro at all, do away with it.

0
source

Source: https://habr.com/ru/post/1795439/


All Articles