what does macro "USE_VAR" used for?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gestorm

    what does macro "USE_VAR" used for?

    Hi all, I found a macro "USE_VAR" in the code of bash-3.2 as
    follows:
    /*file: bash-3.2/shell.c*/
    344 USE_VAR(argc);
    345 USE_VAR(argv);
    346 USE_VAR(env);
    347 USE_VAR(code);
    348 USE_VAR(old_err exit_flag);
    349 #if defined (RESTRICTED_SHE LL)
    350 USE_VAR(saverst );

    I found the definition of this macro at file shell.h as follows:

    116 /* Force gcc to not clobber X on a longjmp(). Old versions of gcc
    mangle
    117 this badly. */
    118 #if (__GNUC__ 2) || (__GNUC__ == 2 && __GNUC_MINOR__ 8)
    119 # define USE_VAR(x) ((void) &(x))
    120 #else
    121 # define USE_VAR(x)
    122 #endif


    I think these code doesn't do anything really , it just control the
    process of compilation. But how does it works? If the "else"
    condition in file shell.h is true, the lines 344~350 in shell.c would
    turn into "; ; ; ; ;".But what would happen in another condition?
    Thanx!
  • Stephen Sprunk

    #2
    Re: what does macro "USE_VAR&q uot; used for?

    Gestorm wrote:
    Hi all, I found a macro "USE_VAR" in the code of bash-3.2 as
    follows:
    /*file: bash-3.2/shell.c*/
    344 USE_VAR(argc);
    345 USE_VAR(argv);
    346 USE_VAR(env);
    347 USE_VAR(code);
    348 USE_VAR(old_err exit_flag);
    349 #if defined (RESTRICTED_SHE LL)
    350 USE_VAR(saverst );
    >
    I found the definition of this macro at file shell.h as follows:
    >
    116 /* Force gcc to not clobber X on a longjmp(). Old versions of gcc
    mangle
    117 this badly. */
    118 #if (__GNUC__ 2) || (__GNUC__ == 2 && __GNUC_MINOR__ 8)
    119 # define USE_VAR(x) ((void) &(x))
    120 #else
    121 # define USE_VAR(x)
    122 #endif
    >
    >
    I think these code doesn't do anything really , it just control the
    process of compilation. But how does it works? If the "else"
    condition in file shell.h is true, the lines 344~350 in shell.c would
    turn into "; ; ; ; ;".But what would happen in another condition?
    Thanx!
    It's a trick that makes sure the compiler sees that a variable is "used"
    even if it's not and therefore doesn't optimize it out or warn about a
    possible coding error.

    S

    Comment

    • Gestorm

      #3
      Re: what does macro "USE_VAR&q uot; used for?

      On Jul 18, 1:17 pm, Stephen Sprunk <step...@sprunk .orgwrote:
      It's a trick that makes sure the compiler sees that a variable is "used"
      even if it's not and therefore doesn't optimize it out or warn about a
      possible coding error.
      >
      Thank you. But why does it use such a strange form? If I do this
      #define USE_VAR(X) &(X)
      would there be anything wrong?

      Comment

      • Kenneth Brody

        #4
        Re: what does macro &quot;USE_VAR&q uot; used for?

        Gestorm wrote:
        >
        On Jul 18, 1:17 pm, Stephen Sprunk <step...@sprunk .orgwrote:
        >
        It's a trick that makes sure the compiler sees that a variable is "used"
        even if it's not and therefore doesn't optimize it out or warn about a
        possible coding error.
        Thank you. But why does it use such a strange form? If I do this
        #define USE_VAR(X) &(X)
        would there be anything wrong?
        [...Original code had: # define USE_VAR(x) ((void) &(x)) ...]

        That might give you a different warning about taking the address of
        the variable and not doing anything about it. By casting the address
        to void, you explicitly tell the compiler "yes, I know I'm throwing
        out the result".

        --
        +-------------------------+--------------------+-----------------------+
        | Kenneth J. Brody | www.hvcomputer.com | #include |
        | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer .h|
        +-------------------------+--------------------+-----------------------+
        Don't e-mail me at: <mailto:ThisIsA SpamTrap@gmail. com>

        Comment

        • Chris Torek

          #5
          Re: what does macro &quot;USE_VAR&q uot; used for?

          In article <95c22d9a-3c03-436d-92e3-251fb11a041e@z1 6g2000prn.googl egroups.com>
          Gestorm <zhcfreesea@126 .comwrote:
          >Hi all, I found a macro "USE_VAR" in the code of bash-3.2 as
          >follows:
          >/*file: bash-3.2/shell.c*/
          344 USE_VAR(argc);
          345 USE_VAR(argv);
          346 USE_VAR(env);
          347 USE_VAR(code);
          348 USE_VAR(old_err exit_flag);
          349 #if defined (RESTRICTED_SHE LL)
          350 USE_VAR(saverst );
          >
          >I found the definition of this macro at file shell.h as follows:
          >
          >116 /* Force gcc to not clobber X on a longjmp(). Old versions of gcc
          >mangle
          >117 this badly. */
          >118 #if (__GNUC__ 2) || (__GNUC__ == 2 && __GNUC_MINOR__ 8)
          >119 # define USE_VAR(x) ((void) &(x))
          >120 #else
          >121 # define USE_VAR(x)
          >122 #endif
          >
          >I think these code doesn't do anything really , it just control the
          >process of compilation. But how does it works?
          It does not (work, that is).

          Read the comment:

          Force gcc to not clobber X on a longjmp().

          Look up setjmp() and longjmp() in your C reference. These are
          macros that "act like" a kind of goto, in which a setjmp() is a
          goto label target, and a longjmp() will go to that label. If your
          C reference is a good one, it will mention certain restrictions on
          using local variables in functions that are the targets of these
          longjmp "go to"s.

          In normal ordinary C, you might write something like:

          void somefunc(T1 parm1, T2 parm2) {
          T3 localvar = initial_value;

          top:
          ... do various things ...
          use(parm1);
          if (some condition) {
          ... maybe change localvar and/or parm1 and/or parm2 ...
          use(parm2);
          use(localvar);
          if (some other condition)
          goto top;
          ... maybe change localvar and/or parm1 and/or parm2 ...
          if (some third condition)
          goto top;
          ...
          }
          ...
          }

          This kind of "goto", built into the language, is only mildly bad,
          as it can only "go" within one particular function, in this case
          the function named somefunc(). If you do go back to the label
          "top", the local variable localvar and the parameters parm1 and
          parm2 hold the new values set by any assignments or adjustments,
          and uses of them will see the new values.

          But suppose, for some reason, you want to be able to "go to" the
          label "top" from a function that somefunc() calls, even indirectly,
          without having to return through all the call layers. That is,
          somefunc() calls a(), and a() calls b(), and b() calls c() which
          calls d() which calls e() and so on up to z(), and then deep inside
          of z() you decide you should "goto top" without ever returning from
          z() or y() or x() or w() or ... all the way back to a(). You *can*
          do this in C, using setjmp() and longjmp(). This is the kind of
          goto you should strive mightily to avoid. The "mild" goto using
          the "goto" keyword is bad enough, but this kind of goto is *terrible*.
          (It is a bit like an exception in C++ except that it cannot even
          be caught. This means that none of a() through y() ever have a
          chance to do any clean up work -- close files, free memory, etc.
          -- that they might need to do. It is possible, though difficult,
          to build a "better" exception-like system that *does* have an
          unwind-protect, using setjmp and longjmp in a stackable fashion,
          but there are pitfalls.)

          Now, the biggest problem with setjmp() and longjmp() is simply their
          existence at all -- but if you *do* use them, they have another
          problem. You, the C programmer, must add a "volatile" qualifier
          to your parameter and local variables (not in absolutely all
          cases, but in enough that you might as well just add it everywhere).
          That is, if you want to rewrite somefunc() to allow a longjmp to
          start over at "top", you must do this:

          #include <setjmp.h>

          jmp_buf label_top;

          void somefunc(volati le T1 parm1, volatile T2 parm2) {
          volatile T3 localvar = initial_value;

          setjmp(label_to p);
          /*
          * At any point, including in functions somefunc() calls,
          * you can:
          * longjmp(label_t op);
          * to "go to" "just after" the setjmp() macro, i.e., right
          * here. This is like using a label like "top:" and doing
          * a "goto top", except that because label_top is a "global
          * variable" of type jmp_buf, it can be goto-ed from anywhere
          * in the program, not just here in somefunc().
          */
          ... do your same various things, tests, etc ...
          }

          But note these "volatile" keywords I added. They are NOT OPTIONAL
          (except in certain obscure circumstances).

          Whoever wrote bash-3.2/shell.c did not realize this and did not
          put in the correct "volatile"s . They then thought that gcc had a
          bug, and put in even more code to attempt to "trick" the compiler
          into behavior as if they had written correct code in the first
          place. (As it happens, some versions of gcc *do* have a bug, even
          if you use the "volatile" keyword as required. But that is not
          what is going on here.)

          The best fix for this problem is to avoid setjmp() and longjmp()
          entirely. The second-best fix is to put in the required "volatile"s .
          The USE_VAR macro is a hack, and is wrong and should be removed.
          --
          In-Real-Life: Chris Torek, Wind River Systems
          Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
          email: gmail (figure it out) http://web.torek.net/torek/index.html

          Comment

          Working...