Topic: An old trick but...


Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 23 Jul 2001 22:55:52 GMT
Raw View
In article <3b5c5140.19225055@news.libero.it>, Gennaro Prota
<gennaro_prota@my-deja.com> writes
>int s = sign(3);       // This invokes the macro
>
>int s = (sign)(3);     // This refers to a specialization
>               //  of the template
>
>
>Is this standard behavior of not?

Yes, and it depends on the preprocessor rules. The grammar for the
preprocessor is rather more picky about parentheses and they are not
redundant in the above instance (while they are for the compiler)

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 24 Jul 2001 09:47:18 GMT
Raw View
Gennaro Prota wrote:
>
> Hi everybody,
>
> this is a trick I learned many months ago from an STLport's forum.
> Anyhow, I didn't find any wording in the standard that justifies it;
> the trick is the following:
>
> surrounding a function name (or a function template-name) with
> parenthesis prevents the compiler to expand a macro of the same name
> (if any) during the preprocessing phase. This applies both when
> writing the function (or function template) definition or when
> referring to the name.
>
> E.g:
>
> #define sign(x) ( (x)>0? +1 : ( (x)<0? -1 : 0 ) )
>
> template <class T>
> inline int (sign)(const T& t) { // Note the parenthesis
>         return t>0? 1 : (t<0? -1 : 0);
> }
>
> int s = sign(3);        // This invokes the macro
>
> int s = (sign)(3);      // This refers to a specialization
>                 //  of the template
>
> Is this standard behavior of not?
>
>                 Thanks,
>                         Genny.

Yes. The relevant clause is 16.3p9: "... Each subsequent instance of the
function-like macro name followed by ( as the next preprocessing token
...".  If the next preprocessing token is ')' rather than '(', then the
function-like macro is not recognised as such, and no substitution
occurs. That frees the tokens to be recognised as a function call,
rather than as an invocation of a function-like macro. Note that
enclosing parenthesis around a function name are perfectly legal, though
redundant. Therefore, what you were told was perfectly correct.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gennaro_prota@my-deja.com (Gennaro Prota)
Date: Tue, 24 Jul 2001 17:46:10 GMT
Raw View
On Tue, 24 Jul 2001 09:47:18 GMT, "James Kuyper Jr."
<kuyper@wizard.net> wrote:

>Gennaro Prota wrote:
>>
>> Hi everybody,
>>
>> this is a trick I learned many months ago from an STLport's forum.
>> [ snip...]
>>
>> surrounding a function name (or a function template-name) with
>> parenthesis prevents the compiler to expand a macro of the same name
>> (if any) during the preprocessing phase. This applies both when
>> writing the function (or function template) definition or when
>> referring to the name.
>>
>> [snip...]

>> Is this standard behavior of not?
>>

>
>Yes. The relevant clause is 16.3p9: "... Each subsequent instance of the
>function-like macro name followed by ( as the next preprocessing token
>...".  If the next preprocessing token is ')' rather than '(', then the
>function-like macro is not recognised as such, and no substitution
>occurs. That frees the tokens to be recognised as a function call,
>rather than as an invocation of a function-like macro. Note that
>enclosing parenthesis around a function name are perfectly legal, though
>redundant. Therefore, what you were told was perfectly correct.
>

Thanks a lot for your replies...now it's very clear to me!
I have only another doubt which arose reading the aforesaid 16.3p9
(nothing dealing with the trick we discussed here, just a matter of
wording):

"Each subsequent instance of the function-like macro name followed by
a ( as the next preprocessing token introduces the sequence of
preprocessing tokens that is replaced by the replacement list in the
definition (an invocation of the macro)."

The sequence of preprocessing tokens introduced by ( is not replaced
by the replacement list itsef, which contains the parameters as single
tokens. Indeed, *parameters* are substituted as described in 16.3.1,
so it seems to me incorrect saying that the entire replacement-list
replaces what is in parenthesis in the macro invocation (BTW, what
about the macro name itself? Does it remain where it is?).

I repeat that my question is about the wording, this time I know the
correct behaviour! ;-)

  Thanks,
    Genny.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 25 Jul 2001 11:08:48 GMT
Raw View
Gennaro Prota wrote:
...
> "Each subsequent instance of the function-like macro name followed by
> a ( as the next preprocessing token introduces the sequence of
> preprocessing tokens that is replaced by the replacement list in the
> definition (an invocation of the macro)."
>
> The sequence of preprocessing tokens introduced by ( is not replaced
> by the replacement list itsef, which contains the parameters as single
> tokens. Indeed, *parameters* are substituted as described in 16.3.1,
> so it seems to me incorrect saying that the entire replacement-list
> replaces what is in parenthesis in the macro invocation ...


I don't see any problem with the wording as it stands. The process takes
place in two steps:
1. The sequence is replaced, exactly as described in 16.3p9.
2. Argument substitution for parameters occurs within the replaced
sequence, as described in 16.3.1.

> ... (BTW, what
> about the macro name itself? Does it remain where it is?).

The macro name is also replaced. The macro name introduces the sequence
that gets replaced; that means that it's a part of the sequence. I'll
grant you - if I didn't already know what was meant, I might have
trouble figuring that out from the somewhat obscure wording.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gennaro_prota@my-deja.com (Gennaro Prota)
Date: Mon, 23 Jul 2001 19:21:05 GMT
Raw View
Hi everybody,

this is a trick I learned many months ago from an STLport's forum.
Anyhow, I didn't find any wording in the standard that justifies it;
the trick is the following:

surrounding a function name (or a function template-name) with
parenthesis prevents the compiler to expand a macro of the same name
(if any) during the preprocessing phase. This applies both when
writing the function (or function template) definition or when
referring to the name.

E.g:

#define sign(x) ( (x)>0? +1 : ( (x)<0? -1 : 0 ) )

template <class T>
inline int (sign)(const T& t) { // Note the parenthesis
        return t>0? 1 : (t<0? -1 : 0);
}


int s = sign(3); // This invokes the macro

int s = (sign)(3); // This refers to a specialization
  //  of the template


Is this standard behavior of not?

  Thanks,
   Genny.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]