-2

Lets say I have:

(please ignore the fact that I am using strncmp in C++)

if (!strncmp(some_str, "constant", strlen("constant"))) {}

The strlen can be evaluated at compile time but it can't be eliminated because the function is not constexpr.

One way around would be (accepted only by g++):

constexpr size_t len = strlen("constant");
if (!strncmp(some_str, "constant", len)) {}

but this is harder to read and less practical.

Is there any way to specify constexpr for a part of a statement?

mmomtchev
  • 2,497
  • 1
  • 8
  • 23

2 Answers2

1

This is fundamentally impossible. Compilers can delay evaluation - do constexpr calculations later, at runtime. But they can't travel back in time. If even a single (evaluated) subexpression is not constexpr, then the whole expression cannot be constexpr.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • In this particular case, everything can be evaluated at compile time. – mmomtchev Oct 20 '22 at 13:15
  • @mmomtchev then if compiler is sophisticated enough, it will evaluate everything in compile time. https://gcc.godbolt.org/z/5nTbTn853 – Revolver_Ocelot Oct 20 '22 at 13:23
  • @mmomtchev and if it isn't, then your "hint" will just cause it to fail with an error. __Because it isn't sophisticated enough to calculate that in compile time.__ – Revolver_Ocelot Oct 20 '22 at 13:24
  • 1
    @mmomtchev: `constexpr` is a bit stronger: **every** C++ compiler must be able to do the evaluation at compile time. And as noted, the Standard does not require that compilers make `strlen` `constexpr`. A compliant compiler can have `strlen` just in its runtime library, which is too late to initialize `constexpr` variables such as `len` in your examples. – MSalters Oct 20 '22 at 13:42
  • The question is discussed at length here: https://stackoverflow.com/questions/25890784/computing-length-of-a-c-string-at-compile-time-is-this-really-a-constexpr – mmomtchev Oct 20 '22 at 13:47
  • 1
    @mmomtchev: Well, that's not `strlen`. That,s a user-defined `length()` function which is literally defined as `constexpr`, unlike `strlen` (since C++ inherits it from C, and C doesn't have `constexpr`, and C++ didn't add it when inheriting) – MSalters Oct 20 '22 at 13:54
  • All the questions asked here have been discussed at great length in the answers and comments - including the fact that `strlen` is a compiler intrinsic and not a runtime library function – mmomtchev Oct 20 '22 at 13:55
  • @mmomtchev: What certain compilers do is not the question. What compilers *have to do* is the question. Compilers can do all kinds of non-standard things; that doesn't make it "C++". – Nicol Bolas Oct 20 '22 at 13:56
  • The original question was if there was any way to specify that an expression should be evaluated at compile time when the function is not `constexpr` - and it seems that the answer might be no - but no one has really answered that – mmomtchev Oct 20 '22 at 14:01
  • @mmomtchev: Your original question talks about applying `constexpr` to part of a statement. Indeed, it doesn't even recognize that `strlen` is *not* `constexpr`, since it says the exact opposite. So if that is what you want to know, maybe you should change your question to ask that. – Nicol Bolas Oct 20 '22 at 14:03
  • I did change it. – mmomtchev Oct 20 '22 at 14:06
  • 1
    @mmomtchev: Compilers **must** have `strlen` as a runtime function, because you can write `&strlen`. Optimizers may add an intrinsic version, but this is strictly optional – MSalters Oct 20 '22 at 14:09
1

You have to be in specific case to force constexpr evaluation, std::integral_constant might help:

if (!strncmp(some_str,
             "constant",
             std::integral_constant<std::size_t, strlen("constant")>()))
{
// ...
}

alias/MACRO might shorten std::integral_constant<std::size_t, strlen("constant")>()

Not sure it is better than your:

constexpr size_t len = strlen("constant");
if (!strncmp(some_str, "constant", len))
{
    // ...
}

Note: I assume that strlen is your own constexpr version (as standard one is not constexpr).

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • This still doesn't work in `clang`: `non-constexpr function 'strlen' cannot be used in a constant expression` – mmomtchev Oct 20 '22 at 13:51
  • @mmomtchev: That's because `strlen` is not a `constexpr` function. If a function is not declared as `constexpr`, it cannot appear in a constant expression. Since that's what `constexpr` *means*. – Nicol Bolas Oct 20 '22 at 13:52
  • @mmomtchev: Seems you miss my last note. Your work around would also fail with non-`constexpr` `strlen`. – Jarod42 Oct 20 '22 at 14:01
  • I updated my question, which is in fact, is there any way to ask the compiler to evaluate an expression at compile time without the functions used being marked as `constexpr` – mmomtchev Oct 20 '22 at 14:12
  • You cannot enforce compile time evaluation of non-constexpr functions. As-if rule allows the compiler to optimize (aggressively) though (but result cannot be stored in constexpr variable anyway). – Jarod42 Oct 20 '22 at 14:27