Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Compile time contants simplification

50 views
Skip to first unread message

jacobnavia

unread,
May 23, 2016, 12:56:44 PM5/23/16
to
Suppose (say) I developed a float128 floating point class using
operator overloading.

How could I dirct the compiler to simplify:

float128_t a = 123.567F128 + 234.5678F128;

to do the addition at compile time?

Wouter van Ooijen

unread,
May 23, 2016, 1:11:27 PM5/23/16
to
Op 23-May-16 om 6:56 PM schreef jacobnavia:
make your opeartor+ constexpr

Wouter "Objects? No thanks!" van Ooijen

jacobnavia

unread,
May 23, 2016, 1:18:03 PM5/23/16
to
Le 23/05/2016 à 19:11, Wouter van Ooijen a écrit :
> make your opeartor+ constexpr
Thanks but that doesn't help me further.

constexpr operator+(const float128_t a,const float128_t b)
{
return a+b;
}

At compile time then, the overloaded + operator would be called?

Wouter van Ooijen

unread,
May 23, 2016, 1:33:09 PM5/23/16
to
Op 23-May-16 om 7:17 PM schreef jacobnavia:
When a function is declared constexpr and is called with constexpr
arguments (which literals are), it is evaluated at compile time.

Wouter

Marcel Mueller

unread,
May 23, 2016, 2:04:20 PM5/23/16
to
On 23.05.16 19.17, jacobnavia wrote:
> constexpr operator+(const float128_t a,const float128_t b)

> At compile time then, the overloaded + operator would be called?

Exactly.

But is up to the compiler to support this feature or not. It might do
it's work at the static initialization if it fails to evaluate the
expression at compile time for some reason.


Marcel

Paavo Helde

unread,
May 23, 2016, 2:18:10 PM5/23/16
to
On 23.05.2016 20:17, jacobnavia wrote:
> Le 23/05/2016 à 19:11, Wouter van Ooijen a écrit :
>> make your opeartor+ constexpr
> Thanks but that doesn't help me further.
>
> constexpr operator+(const float128_t a,const float128_t b)
> {
> return a+b;
> }

This is infinite recursion, you probably want to implement it somehow
otherwise.

> At compile time then, the overloaded + operator would be called?

When you use constexpr, the compiler will ensure that the function *can*
be evaluated at compile time, if passed suitable arguments. If the
function is used in a construct requiring a compile-time value (as in an
array size calculation, etc), then it will be certainly evaluated at
run-time. If it appears in some other context, then it's up to the
compiler to decide whether to evaluate it at compile time or run time
(constexpr implies inline, which is a bit similar in this sense).

In your case I guess you want to make sure that operator+ can be used in
compile-time expressions. This is exactly what constexpr does.

Cheers
Paavo



jacobnavia

unread,
May 23, 2016, 5:26:47 PM5/23/16
to
This is completely impossible. To add two float128_t I need at least
50-60% of the library to extract the components, adjust the decimal
point, do a 256 bit mantissa addition, build the result and a long etc!

I thought the compiler would just call a function in a dll/so or similar.

Marcel Mueller

unread,
May 23, 2016, 5:47:22 PM5/23/16
to
On 23.05.16 23.26, jacobnavia wrote:
> This is completely impossible. To add two float128_t I need at least
> 50-60% of the library to extract the components, adjust the decimal
> point, do a 256 bit mantissa addition, build the result and a long etc!

To be evaluable at compile time all functions you call need to be
constexpr. Some of the runtime function are constexpr. Some are
constexpr with platform dependent extensions. Others are not. So it depends.

> I thought the compiler would just call a function in a dll/so or similar.

No, this is impossible since the binary representations of types are not
portable in general. Note that cross compilation is not that uncommon.


Marcel

Scott Lurndal

unread,
May 24, 2016, 8:40:37 AM5/24/16
to
Use gcc's builtin __uint128_t or __int128_t types :-)

jacobnavia

unread,
May 24, 2016, 6:47:22 PM5/24/16
to
Excuse but I do not understand your point. I am speaking of a full
implementation of IEEE 128 bit floating point format, not integers...

???

Paavo Helde

unread,
May 25, 2016, 4:33:09 AM5/25/16
to
In principle there is no reason why a constexpr function could not
contain all this. One can call also library functions as long as those
functions are constexpr as well.

>
> I thought the compiler would just call a function in a dll/so or similar.

If I understand correctly, your proposal would be that when (shared)
library A contains a non-constexpr function foo() (e.g. for adding
128-bit floats) and library B depends on library A, then library B could
use constexpr functions containing calls to foo(), and the compiler
would actually call this function at compile time and substitute the
result, instead of just linking to the library and calling foo() at run
time.

Interesting idea, but I have not not heard of any such things. For
starters, compiling library B in general does not require the presence
of library A, only headers are needed (and in case of Windows, the stub
.lib file). Dealing with libraries is the concern of the linker which
would be too late. It is true that nowadays linkers are also capable of
generating compiled code (whole program optimization etc), but this is
not mandated. For calling foo(), the linker must first be able to load
the library A into a process (together with all its dependencies which
is not a trivial task), which may become very tricky in case of
cross-compilation etc.

The current constexpr support is much more modest. It does not involve
the linker. It is only the compiler which sees the full source code
(recursively, so no need to mess with any library loading), recompiles
it (probably for the current platform as then it would be easy to call
it) and calls it, probably directly from the memory buffer where it
wrote the binary code, no library or dependencies loading needed.

Note that cross-compilation is very widespread. For example, MSVC
compiler cl.exe is for example a 32-bit program, so compiling 64-bit
applications with MSVC means cross-compilation.

Cheers
Paavo


Chris Vine

unread,
May 25, 2016, 9:05:31 AM5/25/16
to
On Wed, 25 May 2016 11:32:59 +0300
Paavo Helde <myfir...@osa.pri.ee> wrote:
> On 24.05.2016 0:26, jacobnavia wrote:
> > This is completely impossible. To add two float128_t I need at least
> > 50-60% of the library to extract the components, adjust the decimal
> > point, do a 256 bit mantissa addition, build the result and a long
> > etc!
>
> In principle there is no reason why a constexpr function could not
> contain all this. One can call also library functions as long as
> those functions are constexpr as well.
>
> >
> > I thought the compiler would just call a function in a dll/so or
> > similar.
>
> If I understand correctly, your proposal would be that when (shared)
> library A contains a non-constexpr function foo() (e.g. for adding
> 128-bit floats) and library B depends on library A, then library B
> could use constexpr functions containing calls to foo(), and the
> compiler would actually call this function at compile time and
> substitute the result, instead of just linking to the library and
> calling foo() at run time.
>
> Interesting idea, but I have not not heard of any such things. For
> starters, ...
[snip]

I agree with your snipped conclusions, but it has been done in other
languages. Realistically, it requires the same parser to be used for
compile time evaluation of syntactic transformations that is used to
generate code for run time evaluation. Looking at the languages
with (like C++) eager evaluation, OCaml has a relatively modest system
for syntactic macros, although only recently has it been possible to use
the OCaml parser for this. Lisps have had it from the outset: the lisp
parser can parse macros (s-expressions intended to be evaluated at
compile time) using the same parser as it uses to evaluate
s-expressions at runtime. The overriding restriction is that compile
time evaluation can only operate on literals (in this case, code
literals).

It doesn't look particularly worthwhile with C++ because of its strict
syntax; specialist code generators seem a better way of doing it, and
(as I think you mentioned, or if not someone else did) by providing
C++ constexpr versions of non-constexpr C library functions where they
can sensibly be made constexpr. This particularly applies to C
mathematical functions.

Chris
0 new messages