6

I'm implementing a constexpr int foo(); function. In the body of foo(), I want to do something different (and possibly return something different) at compile time and something different at run-time.

With C++20, I can use std::is_constant_evaluated:

constexpr int foo() { return std::is_constant_evaluated() ? 123 : 456 };

but what if I'm using C++17 (or earlier) - what can I do with the same effect?

Note: Compiler-specific solutions are acceptable (though less desirable).

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Why not just have two separate functions? – Karl Knechtel Nov 23 '20 at 14:59
  • @KarlKnechtel how would you distinguish between compile time and runtime with two seperate functions? – 463035818_is_not_an_ai Nov 23 '20 at 15:00
  • 1
    related/dupe: https://stackoverflow.com/questions/46919582/is-it-possible-to-test-if-a-constexpr-function-is-evaluated-at-compile-time – NathanOliver Nov 23 '20 at 15:01
  • 3
    "how would you distinguish between compile time and runtime with two seperate functions?" *I wouldn't.* I would write one function that is only ever used at compile time, to do the thing that needs to be done at compile time; and another that is only ever used at runtime, to do the different thing that needs to be done at runtime. They need to run at different times, and also need to do different things, so I don't see any reason to treat them as related. – Karl Knechtel Nov 23 '20 at 15:11
  • @KarlKnechtel but thats just a "don't do it" answer. I thought there was more to it ;) – 463035818_is_not_an_ai Nov 23 '20 at 15:12
  • Programming is in large part about knowing when not to do things. – Karl Knechtel Nov 23 '20 at 15:12
  • 4
    @KarlKnechtel another huge part is knowing what is possible and how to achieve it – 463035818_is_not_an_ai Nov 23 '20 at 15:13
  • 1
    @KarlKnechtel *Programming is in large part about knowing when not to do things* If that was the case, `std::is_constant_evaluated` would not have been created. There are real use cases for this, like a `pow` function that calculates ate compile time if it can and if not then does the run time version of the function. This is even more true in generic code. – NathanOliver Nov 23 '20 at 15:18
  • 1
    @KarlKnechtel: Because the functions do the same thing; but it needs to happen differently, and/or with different side-effects, at compile-time and at run-time. A concrete example: C++ Standards Committee paper [P1668R1](http://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1668r1.html). – einpoklum Nov 23 '20 at 15:24
  • It does the same thing... differently... potentially with different side effects... and potentially a different return value for the same inputs? – Karl Knechtel Nov 23 '20 at 15:25
  • @KarlKnechtel: Indeed. – einpoklum Nov 23 '20 at 15:27
  • @KamilCuk: 1. Please make that an answer. 2. Do you happen to know if GCC-ish compilers (like clang and NVCC) have this too? – einpoklum Nov 23 '20 at 15:31
  • @KamilCuk: quoting GCC's docs _"determine whether a constexpr function is being called in a constexpr context."* - that's suggests it won't return true if evaluated at compile time outside a constexpr context, which is quite possible. (The same disrepency exists between einpoklum's stated requirements and `std::is_constant_evaluated()`'s behaviour.) – Tony Delroy Nov 23 '20 at 15:40
  • I found also this: https://stackoverflow.com/questions/55288555/c-check-if-statement-can-be-evaluated-constexpr @TonyDelroy well, [the builtin should be 1:1 with `std::is_constant_evaluated`](https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/type_traits#L3287), so if `std::is_constant_evaluated` is what OP is searching for, the builtin does the same. – KamilCuk Nov 23 '20 at 15:40
  • 1
    @KamilCuk: yes, I know that, but OP specifically says _"[something] at compile time and something different at run-time"_, which suggests `std::is_constant_evaluated` was not actually meeting the requirement. – Tony Delroy Nov 23 '20 at 16:43
  • You are aware that `std::is_constant_evaluated` is created to have different algorithms for the same, so the runtime version can use things not allowed at constexpr time? – JVApen Nov 23 '20 at 18:14
  • 1
    @JVApen: 1. Yes. 2. My actual scenario is a bit complicated and not worth going into here. 3. Maybe I want this function to be used in selecting among instantiations of a function which does actually do the same thing, but in different ways? – einpoklum Nov 23 '20 at 20:29

1 Answers1

4

Note: Compiler-specific solutions are acceptable (though less desirable).

Let's mention the most obvious ones:

gcc has __builtin_is_constant_evaluated() at least documented since 9.2.0.

clang has the same builtin since clang-9.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111