Topic: Preprocessor alternatives (Was: Global "if" statement?)


Author: danm@ziplink.net (Dan Muller)
Date: 1997/05/10
Raw View
In article <rf5zpu9kpm9.fsf@vx.cit.alcatel.fr>, james-
albert.kanze@vx.cit.alcatel.fr says...
 > danm@ziplink.net (Dan Muller) writes:
 >
 >  >  A followup to my previous post: A post about a tricky macro bug over in
 >  >  microsoft.public.vc.language made me aware that the "expression" keyword
 >  >  suggestion that I included in my previous post needs the following
 >  >  amendment: The passed-in expression must be evaluated in the caller's
 >  >  scope, not in the function scope. Otherwise names declarated in the
 >  >  function which clash with the caller's namespace could cause strange
 >  >  errors. This also highlights another reason that such a mechanism is
 >  >  useful.
 >  >
 >  >  The macro that had the bug looked like this:
 >  >
 >  >  In article <336af819.4564286@news.pbcs.com>, pc64@compuserve.com says...
 >  >  >   #define wavein(x) \
 >  >  >     { \
 >  >  >       MMRESULT i = (x); \
 >  >  >       if (i != MMSYSERR_NOERROR) { \
 >  >  >         char ac[1024]; \
 >  >  >         waveInGetErrorText(i, ac, sizeof ac); \
 >  >  >         error(#x "\nfailed in file " __FILE__ " at line %d\n%s", \
 >  >  >   __LINE__, ac); \
 >  >  >       } \
 >  >  >     }
 >  >
 >  >  The code that cause the problem looked like this:
 >  >  >  for (int i = 0; i < 100; i++) {
 >  >  >    wavein(waveInPrepareHeader(hwi, &awh[i], sizeof WAVEHDR));
 >  >  >  }
 >  >
 >  >  The "i" defined in the block created by the macro hides the i in the for
 >  >  loop's scope, which means that the expression is evaluated using the
 >  >  wrong definition of i. Another good example of why it would be nice to
 >  >  have some of the preprocessor's power incorporated directly into the
 >  >  language!
 >
 > Of course, in this case, it is already done.  What's wrong with an
 > inline function here?

In this particular case, nothing at all. But preprocessor macros with
arguments have different semantics than inline functions. In particular,
arguments to macros are not always evaluated, whereas arguments to macros
must be evaluated if there is any chance that they have side-effects.
Since we don't have a notion of a pure function without side-effects,
*any* (non-inline?) function call must be assumed to have a side affect.
With C++'s numerous implicit calls (operators, constructors,
destructors), this covers a lot of expressions.

--
Dan Muller   danm@ziplink.net
http://www.ziplink.net/~danm
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/05/06
Raw View
danm@ziplink.net (Dan Muller) writes:

 >  A followup to my previous post: A post about a tricky macro bug over in
 >  microsoft.public.vc.language made me aware that the "expression" keyword
 >  suggestion that I included in my previous post needs the following
 >  amendment: The passed-in expression must be evaluated in the caller's
 >  scope, not in the function scope. Otherwise names declarated in the
 >  function which clash with the caller's namespace could cause strange
 >  errors. This also highlights another reason that such a mechanism is
 >  useful.
 >
 >  The macro that had the bug looked like this:
 >
 >  In article <336af819.4564286@news.pbcs.com>, pc64@compuserve.com says...
 >  >   #define wavein(x) \
 >  >     { \
 >  >       MMRESULT i = (x); \
 >  >       if (i != MMSYSERR_NOERROR) { \
 >  >         char ac[1024]; \
 >  >         waveInGetErrorText(i, ac, sizeof ac); \
 >  >         error(#x "\nfailed in file " __FILE__ " at line %d\n%s", \
 >  >   __LINE__, ac); \
 >  >       } \
 >  >     }
 >
 >  The code that cause the problem looked like this:
 >  >  for (int i = 0; i < 100; i++) {
 >  >    wavein(waveInPrepareHeader(hwi, &awh[i], sizeof WAVEHDR));
 >  >  }
 >
 >  The "i" defined in the block created by the macro hides the i in the for
 >  loop's scope, which means that the expression is evaluated using the
 >  wrong definition of i. Another good example of why it would be nice to
 >  have some of the preprocessor's power incorporated directly into the
 >  language!

Of course, in this case, it is already done.  What's wrong with an
inline function here?

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
     -- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Darron.Shaffer@beasys.com (Darron Shaffer)
Date: 1997/05/07
Raw View
In article <MPG.dd67fa8e16df8898972c@news.ziplink.net>, danm@ziplink.net
(Dan Muller) wrote:

...
>
>The macro that had the bug looked like this:
>
>In article <336af819.4564286@news.pbcs.com>, pc64@compuserve.com says...
>>   #define wavein(x) \
>>     { \
>>       MMRESULT i = (x); \
>>       if (i != MMSYSERR_NOERROR) { \
>>         char ac[1024]; \
>>         waveInGetErrorText(i, ac, sizeof ac); \
>>         error(#x "\nfailed in file " __FILE__ " at line %d\n%s", __LINE__,
>> ac); \
>>       } \
>>     }
>
>The code that cause the problem looked like this:
>>  for (int i = 0; i < 100; i++) {
>>    wavein(waveInPrepareHeader(hwi, &awh[i], sizeof WAVEHDR));
>>  }
>

Bad!

Try:

inline void
RealWavein(const char * message, int line, MMRESULT rslt)
{
   if (rslt != MMSYSERR_NOERROR)
   {
      char ac[1024];
      waveInGetErrorText(rslt, ac, sizeof ac);
      error(message, line, ac);
   }
}

#define wavein(x)  \
   RealWavein(#x "\nfailed in file " __FILE__ " at line %d\n%s", __LINE__, x)


Look, no argument problems -- use C++ for scope & the preprocessor for
stringizing & source location info.

I suggest a more "unusual" name for any macro.  Don't tempt someone into
trying to declare a class member with the same name.
--
Darron Shaffer
Darron.Shaffer@beasys.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: danm@ziplink.net (Dan Muller)
Date: 1997/05/04
Raw View
A followup to my previous post: A post about a tricky macro bug over in
microsoft.public.vc.language made me aware that the "expression" keyword
suggestion that I included in my previous post needs the following
amendment: The passed-in expression must be evaluated in the caller's
scope, not in the function scope. Otherwise names declarated in the
function which clash with the caller's namespace could cause strange
errors. This also highlights another reason that such a mechanism is
useful.

The macro that had the bug looked like this:

In article <336af819.4564286@news.pbcs.com>, pc64@compuserve.com says...
>   #define wavein(x) \
>     { \
>       MMRESULT i = (x); \
>       if (i != MMSYSERR_NOERROR) { \
>         char ac[1024]; \
>         waveInGetErrorText(i, ac, sizeof ac); \
>         error(#x "\nfailed in file " __FILE__ " at line %d\n%s", __LINE__,
> ac); \
>       } \
>     }

The code that cause the problem looked like this:
>  for (int i = 0; i < 100; i++) {
>    wavein(waveInPrepareHeader(hwi, &awh[i], sizeof WAVEHDR));
>  }

The "i" defined in the block created by the macro hides the i in the for
loop's scope, which means that the expression is evaluated using the
wrong definition of i. Another good example of why it would be nice to
have some of the preprocessor's power incorporated directly into the
language!

--
Dan Muller   danm@ziplink.net
http://www.ziplink.net/~danm
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]