From: Andy Gibbs <andyg1001@hotmail.co.uk>
To: "Richard Guenther" <richard.guenther@gmail.com>
Cc: <gcc-patches@gcc.gnu.org>
Subject: Re: [C++ Patch] __builtin_choose_expr *bump*
Date: Fri, 21 Oct 2011 14:29:00 -0000 [thread overview]
Message-ID: <BLU0-SMTP3832C5A09DCDC2BCBE85AADE7E80@phx.gbl> (raw)
In-Reply-To: <CAFiYyc3GkPgsvcm=S23qD9=Gt+4JuMh+xaUWk0tKRBM4yT=a+A@mail.gmail.com>
On Friday, October 21, 2011 12:04 PM, Richard Guenther wrote:
> What's the motivation for this? Why can't it be implemented using C++
> features such as templates and specialization?
Sorry for the delay in my reply.
The motivation, simply put, is to be able to create both templates and
macros that choose between two or more courses of action at compile time and
do not generate code for the unchosen action(s), nor (importantly) cause
compiler errors if the unchosen action(s) should be ill-formed. The end aim
is in the generation of source code libraries for compile-time evaluation.
An example in the template domain would be, having template specialisation
without actually needing to specialise the template. Ordinarily,
specialising a template requires a copy to be made and modified according to
the specialisation. If the "base" template is changed, the specialisation
also needs to be so adapted. Missing one specialisation in a long list
leads to unpredictable problems (yes, there is bitter experience here!). If
the majority of code is identical then it makes sense to try to either
factor out the identical code and use some meta-template If struct or other
such magic to limit the scope of the template specialisation. This can
become brain-bending if not impossible if, for example, any of the relevant
expressions cannot be parameters into a meta-template construct. It can
also make the code very difficult to follow and debug. In these cases,
__builtin_choose_expr can be beneficial to avoid the need to specialise,
while keeping the clarity and breadth of the template's intended function.
When it comes to macros, the use of __builtin_choose_expr can be very useful
where one of the expressions would cause a compiler error. An example of
such a macro is as follows:
#define CONST(v) \
__builtin_choose_expr(util::can_use_const_wrapper<decltype(v)>::value, \
(util::const_wrapper<decltype(v),(v)>::value) : \
([&](){ constexpr auto o = (v); return o; })())
namespace util
{
template <typename T, T t>
struct const_wrapper
{ static constexpr T value = t; };
template <typename T>
struct can_use_const_wrapper; /* code removed to keep example short! */
/* value = true for types that can be used in template value parameters */
}
This is a part of a larger library of code for constexpr functions, a
majority of which implement algorithms in such a way that the compiler can
evaluate them but which if evaluated at run-time would have a huge
performance hit (e.g. CRC calculation on a string). In this library, a
second macro FORCE_CONSTEXPR is used to ensure these functions cannot be
called at run-time or even inlined, but only evaluated at compile-time. The
CONST macro is then used, among other things, to hint to the compiler that
it needs to evaluate at compile-time.
If __builtin_choose_expr in the CONST macro was replaced with "? :" then the
code using it would fail to compile in certain situations, notably because
C++ only permits certain types as template value parameters. However, it is
not sufficient either to simply use the lambda expression alone since this
fails with compiler errors in other situations. This is, I think, one
example where it is not possible to use templates to get round the
problem?...
There is a further use of __builtin_choose_expr in this constexpr library,
which is similar to its use in C, which is to enable a macro function to
wrap and choose between a compile-time version of the algorithm and a
run-time version of the algorithm, for example:
#define CrcString(str) (__builtin_choose_expr(__builtin_constant_p(str), \
CONST(CrcString_compiler(str)), \
CrcString_runtime(str)))
auto string = CrcString("test");
This might of course be implemented using "? :", but only if
CrcString_compiler(...) and CrcString_runtime(...) return compatible types,
which need not be so with __builtin_choose_expr.
I hope this gives you some feeling for how __builtin_choose_expr may be
used, or for that matter how I use it. I expect that others will find much
more impressive uses!
Thanks
Andy
next prev parent reply other threads:[~2011-10-21 13:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-19 12:26 [C++ Patch] __builtin_choose_expr Andy Gibbs
2011-10-21 10:40 ` [C++ Patch] __builtin_choose_expr *bump* Andy Gibbs
2011-10-21 10:47 ` Richard Guenther
2011-10-21 14:29 ` Andy Gibbs [this message]
2011-10-21 15:28 ` Joseph S. Myers
2011-10-21 15:39 ` Andy Gibbs
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BLU0-SMTP3832C5A09DCDC2BCBE85AADE7E80@phx.gbl \
--to=andyg1001@hotmail.co.uk \
--cc=gcc-patches@gcc.gnu.org \
--cc=richard.guenther@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).