C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] a common C/C++ core specification

From: Florian Weimer <fw_at_[hidden]>
Date: Tue, 10 Mar 2020 16:32:40 +0100
* Jens Gustedt via Liaison:

> Hi everybody,
> for those that have not seen it yet, the following WG14 paper may be
> interesting for you folks here
>
> N2494 2020/03/07 Gustedt, a common C/C++ core specification
>
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2494.pdf
>
> This is my (personal) attempt to see where we should go to increase the
> intersection of the two languages, or, at least, where we should clearly
> mark the differences. And a lot more ...

Interesting.

However, I think _Generic is largely a dead-end for things like math
functions where even moderate nesting of expressions can be expected.
The problem is the separation into translation phases. A macro
wrapping _Generic first needs to expanded, including all its
alternatives, recursively. Only in later translation phases, the
expression is again reduced to something manageable. In theory,
merging translation phases could avoid this problem, but that looks
like a kludge to me.

For example, I don't think a fully usable implementation of <tgmath.h>
using _Generic is possible. Joseph Myers probably has more insights
about this topic. Here is what he wrote about support for an
alternative implementation in GCC:

commit 3ca0dc603213b2ad5ffbcf1a443a102bef96053a
Author: Joseph Myers <joseph_at_[hidden]>
Date: Wed Nov 15 01:53:45 2017 +0000

    Add __builtin_tgmath for better tgmath.h implementation (bug 81156).
    
    Various implementations of C99/C11 <tgmath.h> have the property that
    their macro expansions contain many copies of the macro arguments, so
    resulting in exponential blowup of the size of macro expansions where
    a call to such a macro contains other such calls in the macro
    arguments.
    
    This patch adds a (C-only) language feature __builtin_tgmath designed
    to avoid this problem by implementing the <tgmath.h> function
    selection rules directly in the compiler. The effect is that
    type-generic macros can be defined simply as
    
    #define pow(a, b) __builtin_tgmath (powf, pow, powl, \
                                        cpowf, cpow, cpowl, a, b)
    
    as in the example added to the manual, with each macro argument
    expanded exactly once. The details of __builtin_tgmath are as
    described in the manual. This is C-only since C++ uses function
    overloading and just defines <ctgmath> to include <ccomplex> and
    <cmath>.
    […]

<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81156>

C++ function overloading does not have this problem, even when
implemented inefficiently: types for the most nested expression are
determined first and then fixed, so the combinatorial explosion
inherent to _Generic-based macros does not happen.

Received on 2020-03-10 10:37:04