News for hackers. Stuff that matters.
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @05:41AM (#28886658)
> C++ has supported compile-time evaluation of first-class functions for over ten years, while C is still limited to using second-class language features in compile-time contexts

It's funny that of all the gazillion features C++ has supported a for well over a decade the C folks have been missing out on, they pick exactly the one superfluous keyword in C++ to cherrypick onto C. You have to wonder what will happen if/when C++ removes the requirement for the keyword later.

Re:Proposal to add constexpr to C [pdf] by marcodiego on Saturday October 16, 2021 @09:41AM (#28887802)
I think you're completely ignoring more radical proposed changes like lambdas: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2738.pdf and more modern error handling: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2361.pdf

Also consider that proposals must satisfy http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2021.htm small list of relevant points:

  4. Avoid “quiet changes.” 

  6. Keep the spirit of C.

  9. Minimize incompatibilities with C90 (ISO/IEC 9899:1990).

  11. Maintain conceptual simplicity.
Re:Proposal to add constexpr to C [pdf] by bonzini on Saturday October 16, 2021 @01:27PM (#28889538)
The two things I would add to C are RAII (like GCC __attribute__((cleanup)) and glib's g_autoptr wrappers), and variant types (mostly so that we could have an equivalent of Rust's Result type).
Re:Proposal to add constexpr to C [pdf] by enriquto on Saturday October 16, 2021 @04:33PM (#28891232)
RAII is mostly already there, or at least a C-spirited version of it, thanks to variable length arrays. Unfortunately, there's little compiler support for large vla, both clang and gcc seem to choke on them because they put them on the stack (which is the naive implementation of vla).
Re:Proposal to add constexpr to C [pdf] by bonzini on Saturday October 16, 2021 @05:00PM (#28891465)
How would variable length arrays, for example, help with releasing a mutex on early returns from a function?
Re:Proposal to add constexpr to C [pdf] by enriquto on Saturday October 16, 2021 @05:30PM (#28891742)
They wouldn't, of course! Releasing resources silently (other than the memory of automatic variables) is very un-C-like.
Re:Proposal to add constexpr to C [pdf] by bonzini on Sunday October 17, 2021 @03:33AM (#28894652)
It's not silent, you do declare that you want it released; you just do it before and it applies to all early returns. For example

    MUTEX_LOCK_GUARD(&lock)
        for (i = 0; i < n; i++)
            if (a[i] == x)
                return i;
    return -1;
Real world example here: https://github.com/qemu/qemu/blob/master/block/iscsi.c#L325

And the implementation: https://github.com/qemu/qemu/blob/master/include/qemu/lockab... (after inlining, the abstraction is completely zero cost).

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @05:57PM (#28891955)
> RAII is mostly already there

>> Releasing resources silently (other than the memory of automatic variables) is very un-C-like

The "R" is literally "resource", right? Sounds like instead of RAII you just meant unique_ptr.

Though I beg to differ on whether releasing memory automatically is any different from releasing other resources as far as being C-like is concerned!

Re:Proposal to add constexpr to C [pdf] by pjmlp on Sunday October 17, 2021 @02:38AM (#28894464)
VLA are out of the races since C11.

So you can forget about compilers caring to improve the quality of an optional feature, that was even cleaned from Linux kernel.

Re:Proposal to add constexpr to C [pdf] by enriquto on Sunday October 17, 2021 @05:24AM (#28895089)
I'll give you my VLA and my complex.h when you pry it from my cold, dead hands.
Re:Proposal to add constexpr to C [pdf] by pjmlp on Sunday October 17, 2021 @05:50AM (#28895205)
You are always free to keep your own fork of GCC.
Re:Proposal to add constexpr to C [pdf] by huhtenberg on Saturday October 16, 2021 @12:59PM (#28889281)
Not sure if you were trying to make this point, but as others have noted constexpr almost certainly violates #11 (by mixing run-time and compile-time variables) and through that it also violates #6.
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @10:52AM (#28888250)
I'm not ignoring anything, I just mentioned C++ has had a ton of features over C, some well over a decade (and some just about and some newer).

Moreover I can't even see how I could've mentioned lambdas. They have a superfluous keyword? Which one?

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @02:42PM (#28890287)
Edit: Whoops, just had a chance to read these comments more carefully. I didn't realize you're talking about C rather than C++. I didn't ignore them; I just wasn't aware of those proposals. (Certainly I haven't seen them on HN, and I don't keep up with all the proposals.)
Re:Proposal to add constexpr to C [pdf] by nuerow on Saturday October 16, 2021 @06:22AM (#28886825)
> It's funny that of all the gazillion features C++ has supported a for well over a decade the C folks have been missing out on, they pick exactly the one superfluous keyword in C++ to cherrypick onto C.

It looks to me that it's a significant improvement that's also a very low hanging fruit, given that C/C++ compilers that already support C++'s constexpr can trivially support it for C as well.

Re:Proposal to add constexpr to C [pdf] by NavinF on Saturday October 16, 2021 @06:58AM (#28886999)
Besides that, I suspect nobody in this thread has looked at what compilers output.

Compare the following programs that multiply 2*2:

https://godbolt.org/z/avsac77aa

https://godbolt.org/z/Mznhrf1sq

The only difference between them is that `len` and `result` are declared constexpr in the first program.

Notice how without constexpr, both clang and gcc generate a slow call to mul() inside main() instead of just calculating 2*2 at compile time.

I'm sure you could use LLVM opt to force to compiler to try harder than -O3 (and maybe that should be the default), but that will also make compile time longer. Real code is way harder to optimize than my 18 lines that are all in 1 file.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @11:10AM (#28888394)
> I'm sure you could use LLVM opt to force to compiler to try harder than -O3 (and maybe that should be the default), but that will also make compile time longer. Real code is way harder to optimize than my 18 lines that are all in 1 file.

Evaluating code at compile time is not harder or even as much work as than optimizing it. If you ever wrote an interpreter you know that it's much simpler than optimized codegen. You can evaluate unoptimized code at compile time perfectly fine, and deducing whether that is possible is extremely fast in comparison. Which is why in C++ you see people litter constexpr everywhere they can regardless of whether the code is -O0 or -O3.

Re:Proposal to add constexpr to C [pdf] by NavinF on Saturday October 16, 2021 @11:36AM (#28888576)
Hey, by all means fix clang and gcc so that my example no longer requires a runtime call to mul().

After all, evaluating code at compile time is easy right?

If you succeed in solving this problem in general, feel free to propose a change to the language that allows the use of expressions such as `mul(arr, arr+len)` anywhere you'd normally be required to use a constant. (That's what constexpr already achieves today)

Btw I mentioned that you can make the compiler try harder with LLVM opt because constant-folding is an optimization. I dunno why you bring up codegen.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @02:46PM (#28890320)
> Hey, by all means fix clang and gcc so that my example no longer requires a runtime call to mul().

They can just pretend every inline function has constexpr in front of it, and fall back to compiling them if they fail to evaluate it as constexpr. The constexpr doesn't tell the compiler anything it didn't already know or have to verify anyway. And bear in mind much of the standard library already has constexpr in front of it (and that's a pretty strong signal that it should've been implicit IMO). I don't know Clang or GCC's codebases to know exactly what to modify off the top of my head, but I'm pretty sure adding an extra 'constexpr' internally in the front-end would be utterly trivial as far as compilers go. No need for any optimizations to get involved (and it's important to understand this).

Re:Proposal to add constexpr to C [pdf] by manwe150 on Saturday October 16, 2021 @01:06PM (#28889331)
Since the compiler must verify the expression is constexpr-valid, it could annotate that automatically instead. However, I believe that generally the standard requires that the keyword be explicit so that compilers agree on what are legal programs, and don’t just declare it to be implementation-defined for what is legal in const-initializer contexts.

But in clang, you’d need an frontend-optimization framework to do that reliably (due to recursion), and it doesn’t have one. In llvm, the Attributer framework is still relatively new, but is progressing towards that.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @07:28PM (#28892517)
> However, I believe that generally the standard requires that the keyword be explicit so that compilers agree on what are legal programs, and don’t just declare it to be implementation-defined for what is legal in const-initializer contexts.

The standard could just declare that anything that could be constexpr-evaluable must be evaluated at compile time up to a depth of at least N, or something like that, after which it is permitted (but not obligated) to be evaluated at runtime. Just like with templates, except over there the implementation just errors out if the template gets too complicated or impossible to evaluate. The standard already has minimum criteria like these for a ton of other cases so this wouldn't be any different to justify a keyword for it.

Re:Proposal to add constexpr to C [pdf] by saagarjha on Saturday October 16, 2021 @06:55AM (#28886990)
Not every C compiler is a C++ compiler.
Re:Proposal to add constexpr to C [pdf] by boulos on Saturday October 16, 2021 @02:14PM (#28890033)
... constexpr isn't superfluous.

The compiler can/could/does absolutely infer that a thing is a compile time constant and do it for you.

But, if you declare a thing constexpr and someone updates some part of it to be !constexpr, you get a nice compiler error. Without labeling the value as constexpr, you don't get that certainty.

Edit: is the argument that const static is also that? (If so, only for direct initialization of structures / you still can't have the equivalent of a constexpr function).

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @03:06PM (#28890492)
> But, if you declare a thing constexpr and someone updates some part of it to be !constexpr, you get a nice compiler error. Without labeling the value as constexpr, you don't get that certainty.

That's not really true. You don't get that "certainty" with constexpr either:

  template<class T> T f(T);
  template<class T> constexpr T g(T x) { return f(x); }
Notice you won't even get a warning with -Weverything under Clang!

> Edit: is the argument that const static is also that? (If so, only for direct initialization of structures / you still can't have the equivalent of a constexpr function).

For variables, const static should probably evaluate at compile time whenever possible, like you mentioned.

For functions, constexpr is really useless (again, see above as just one example) and an inline declaration serves pretty much the same practical purpose. I think you're thinking of 'consteval', which is at least not completely useless, so it's a little easier to justify. Even then, it should've probably been an attribute rather than a keyword.

Re:Proposal to add constexpr to C [pdf] by boulos on Saturday October 16, 2021 @09:47PM (#28893275)
Hmm, is that just because of the template resolution? (and so wouldn't apply to constexpr in C)

AFAICT, something about the template declarations is making the call of f(x) to be "who could know" (which should just be fail).

The same thing with concrete types says that f isn't constexpr [3]. And you have to make it actually constexpr by removing the static from counter [4].

[1] https://docs.microsoft.com/en-us/cpp/cpp/constexpr-cpp?view=...

[2] https://godbolt.org/z/7rGWbP1xz

[3] https://godbolt.org/z/5WjMr3Kjv

[4] https://godbolt.org/z/v9rc1j9zc

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @10:13PM (#28893388)
I think it's because of ADL, which also wouldn't apply in C.
Re:Proposal to add constexpr to C [pdf] by dataflow on Sunday October 17, 2021 @03:19PM (#28898975)
Edit: Actually maybe I'm wrong... even if you scope it it won't warn you.
Re:Proposal to add constexpr to C [pdf] by AlexanderDhoore on Saturday October 16, 2021 @05:49AM (#28886681)
Do you mean that C++ could have done without `constexpr` and could have used the existing `const`? Because that has been my feeling for a very long time. Why not expand the meaning of const in certain contexts. Compilers know if something can be evaluated at compile-time. No need for me to tell them explicitly.
Re:Proposal to add constexpr to C [pdf] by zarzavat on Saturday October 16, 2021 @05:58AM (#28886729)
It's not the same. e.g.

   const int x = readInput();
cannot be constexpr. Consider constexpr as a compile time assertion that a given symbol is available at compile time. If you didn't have the constexpr keyword then you would have have to inspect the definition to determine that every subexpression is constexpr.
Re:Proposal to add constexpr to C [pdf] by nine_k on Saturday October 16, 2021 @06:20AM (#28886817)
Why not

  const int x = const foo(bar(y));

?
Re:Proposal to add constexpr to C [pdf] by mpyne on Saturday October 16, 2021 @01:57PM (#28889877)
The compile can (and will) do that at run time, it just won't let the code alter x afterwards (either at compile time or run time)
Re:Proposal to add constexpr to C [pdf] by SuchAnonMuchWow on Saturday October 16, 2021 @01:53PM (#28889838)
You should check Zig comptime keyword, which does exactly that. Its the feature from zig I miss the most in C.
Re:Proposal to add constexpr to C [pdf] by User23 on Saturday October 16, 2021 @04:25PM (#28891162)
That sounds like a subset of EVAL-WHEN[1].

[1] http://clhs.lisp.se/Body/s_eval_w.htm

Re:Proposal to add constexpr to C [pdf] by AlexanderDhoore on Saturday October 16, 2021 @06:02AM (#28886740)
"inspect the definition"

Yes, that's what I meant with "the compiler can do it".

Re:Proposal to add constexpr to C [pdf] by zabzonk on Saturday October 16, 2021 @06:12AM (#28886786)
Not given C and C++ separate file compilation.
Re:Proposal to add constexpr to C [pdf] by zarzavat on Saturday October 16, 2021 @07:22AM (#28887099)
That might be OK in an IDE driven language such as Java, but I doubt the neckbeards writing C in a plain text editor would go for that level of implicitness. In C++ it might be more acceptable since you practically need an IDE since C++11 to resolve all the auto type inference.
Re:Proposal to add constexpr to C [pdf] by foxfluff on Saturday October 16, 2021 @08:08AM (#28887273)
C neckbeard here. I do fully hope and expect and assume the compiler to fold constants and figure out as much at compile time as it can. This is the kind of optimization that doesn't make the code harder to reason about, even when coding with ed, since the logic and ultimate result of these expressions does not change.

Heavy type inference, overloading, and inheritance are a completely different beast and they make the code a lot more opaque.

Re:Proposal to add constexpr to C [pdf] by pjmlp on Saturday October 16, 2021 @06:25AM (#28886850)
Yes, all the constsomething is superfluous, as proven by Circle.

https://www.circle-lang.org/

Unfortunately, there is a big political war ongoing, so instead C++ keeps collecting const.... keywords.

Re:Proposal to add constexpr to C [pdf] by voldacar on Saturday October 16, 2021 @08:11AM (#28887297)
"Constexpr" is possibly the most hideous keyword in any programming language. My eyes vomit a little each time I read it.

They could have just used "pure" like in D, but this is C++, so that would be too sane and obvious.

Re:Proposal to add constexpr to C [pdf] by hmfrh on Saturday October 16, 2021 @08:26AM (#28887370)
Introducing a new keyword means that all existing code that uses the new keyword as an identifier will break. That's why the `constexpr` keyword is deliberately weird.

It's also why they reuse keywords like `using`.

Re:Proposal to add constexpr to C [pdf] by kevin_thibedeau on Saturday October 16, 2021 @02:50PM (#28890348)
They could just use the reserved keyword naming like the C committee does.
Re:Proposal to add constexpr to C [pdf] by pjmlp on Saturday October 16, 2021 @08:17AM (#28887325)
Politics, check the outcome of the networking vote.
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @10:58AM (#28888296)
No, not all const is superfluous. You don't want const-able method to be const. And const is a property of the declaration, not the definition. But constexpr is superfluous. It's something the compiler can infer purely from looking at the definition, and it has little to no "design" value like const does.
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @03:27PM (#28890685)
> You don't want const-able method to be const.

Edit, typo: I meant "You don't want every const-able method to be const."

Re:Proposal to add constexpr to C [pdf] by nly on Saturday October 16, 2021 @07:56AM (#28887223)
I can't confirm in this specific case but, more often than not, the reason for these redundancies is a fraction of the committee felt uncomfortable with the implicit solution, so the keyword got added.
Re:Proposal to add constexpr to C [pdf] by pjmlp on Saturday October 16, 2021 @08:16AM (#28887322)
There is a video about the story background, where a group of kids play the role of the committee voting down Circle.
Re:Proposal to add constexpr to C [pdf] by nly on Saturday October 16, 2021 @02:48PM (#28890335)
Link?
Re:Proposal to add constexpr to C [pdf] by pjmlp on Saturday October 16, 2021 @03:54PM (#28890903)
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @10:56AM (#28888280)
Basically, yeah.

You don't even need 'const' for this. Under the as-if rule, subsets of the program could always already be evaluated at compile time and have the result substituted in the program. Compilers already did that when they had the definition handy. Like just do int x = f(5); and then define int f(int x) { return x * 2; } and you'll get int x = 10; in any compiler without any keywords whatsoever. The constexpr keyword just cluttered the code for no good reason.

Re:Proposal to add constexpr to C [pdf] by NavinF on Saturday October 16, 2021 @11:25AM (#28888502)
In theory compilers can always optimize constant expressions, but they don't IRL. See my example above where I multiply the elements of an array containing {2,2}: https://news.ycombinator.com/item?id=28886999

My code is C style and unrealistically simple, yet the compiler can't even constant-fold that.

If you've looked at the output of real compilers, you'd know that it's unrealistic for a language to let you to use the result of an arbitrary function call where you'd normally use a constant.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @11:30AM (#28888529)
I'd already replied to you on that example and explained this has nothing to do with optimizations as far as performance and mechanics go. The only relevance of optimizations is to show that the language semantics always permitted it. Not to suggest an optimize needs to be run to actually do this.
Re:Proposal to add constexpr to C [pdf] by comex on Saturday October 16, 2021 @03:04PM (#28890470)
It depends.

For one thing, constexpr guarantees that errors will produce compilation failures. (At least it guarantees that when used in certain ways; unfortunately C++ overcomplicates things.) In a version of C that doesn't have an explicit constexpr keyword but does allow the compiler to treat arbitrary variables as constants, you could perhaps approximate this by using a value in a context that forces it to be a constant expression… e.g. `const int x = foo(); _Static_assert(x == x);`. But that's a hack. Much better to have an explicit way to say "please evaluate this at compile time".

Also, suppose the user doesn't use an expression in a way that forces it to be evaluated at compile time, but you still want to allow the compiler to do constant evaluation for the sake of faster runtime performance or smaller code size. In this example, should fib(35) be evaluated at compile time or runtime?

    unsigned int fib(int n) {
        return n <= 1 ? 1u : fib(n - 1) + fib(n - 2);
    }

    int main() {
        fib(26);
    }
It depends on the user's intent. In this case, evaluating fib(35) takes less than a millisecond at runtime on my computer, but evaluating it as constexpr with clang requires about a full second. (After all, naive fib performs an exponential number of recursive calls.) Sounds like it's probably a job for runtime… unless the user really values runtime performance or code size more than compile times (maybe they're targeting a really slow CPU), in which case they might prefer it to be done at compile time. Best to give them a choice.

Making things worse, the compiler has no real way of knowing how long something will take to constant-evaluate other than trying and seeing. It can give up after a timeout, but if the timeout isn't very tiny, it risks wasting a lot of time on aborted constant evaluation attempts. Therefore, while optimizers already try to perform opportunistic constant folding, they have to be very conservative with it. This problem doesn't occur if the compiler knows that something should be constant-evaluated because the user has marked it as such.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @03:14PM (#28890565)
> In this example, should fib(35) be evaluated at compile time or runtime?

In that example, at compile time. If you write fib(35) you deserve to have to wait for the compiler to do it at compile time instead of at run time. (I'm not saying this to be funny. I'm really trying to make a point. You really do need a realistic example to motivate your side of the argument. If they're hard to come up with, that's kind of my point.) And honestly if I wrote that I would fully expect my compiler's optimizer to already waste that time constant-folding anyway; if I was concerned about its compile time I wouldn't write that even without constexpr.

> Best to give them a choice.

A need for that choice (assuming it's even necessary here, which is debatable, see above) doesn't mean you need a new keyword, especially not for functions. It could've been an attribute, and whatever it is, it only really makes sense on variables, not functions. And whatever it is, turning it into an exclusion instead of an inclusion would probably make sense here, seeing as how so much of the standard library has constexpr in front of it.

Re:Proposal to add constexpr to C [pdf] by bobthebuilders on Saturday October 16, 2021 @07:12PM (#28892419)
What? Why would fib(35) be evaluated at comple time? What if it's fib(1500)? The computers I want to run the program on is way faster than the pi I use for development.
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @07:18PM (#28892451)
> What? Why would fib(35) be evaluated at compile time?

Same reason why fib(2) might be.

> What if it's fib(1500)?

Are you familiar with exponential growth? This would take longer than the heat death of the universe, whether you evaluate it at compile time or run time...

Re:Proposal to add constexpr to C [pdf] by bobthebuilders on Sunday October 17, 2021 @03:17PM (#28898961)
Right, but maybe a military supercomputer could compute such a thing. I know my pi surely can't.
Re:Proposal to add constexpr to C [pdf] by electroly on Saturday October 16, 2021 @02:46PM (#28890318)
If nothing else, constexpr as a keyword lets you force it to happen and fail if it can't happen, rather than silently reverting back to runtime execution. I don't think it's certain that C++ will remove the keyword.
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @02:56PM (#28890403)
constexpr on a variable declaration does that (i.e. it's still superfluous on function declarations, which is where it clutters code by far the most). But even for that, there was already std::integral_constant which would've forced this, and they could've just updated it to C++20 via template<auto Value> static const auto constant = Value; if they really wanted to. Or added an [[attribute]] for variable declarations, just like how we have [[likely]] etc. No need to introduce a whole new keyword for this, especially not in a ton of other contexts.
Re:Proposal to add constexpr to C [pdf] by electroly on Saturday October 16, 2021 @03:29PM (#28890699)
Those suggestions, honestly, don't sound better than the keyword to me. I think you're taking it as a given that if a keyword can be avoided, it must be avoided, but I don't fundamentally agree with that at all.
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @03:37PM (#28890763)
I mean your (only?) argument for the constexpr keyword at this point is "it can be a keyword and I feel like it should be, even when I acknowledge it's redundant" then by all means go ahead. Personally I don't think that's a good way to do language design, but I can't argue with subjective feelings and aesthetics and I was never intending to. I'm pretty sure that's not one of the bases on which it made it into the standard though, and those are what I'm trying to address.
Re:Proposal to add constexpr to C [pdf] by jcelerier on Saturday October 16, 2021 @09:18AM (#28887678)
> You have to wonder what will happen if/when C++ removes the requirement for the keyword later.

I don't think it's that simple. You need a way to differentiate code that runs at compile time and code that runs at runtime (because at compile time you can afford a "slow" algorithm, while at run-time you'll be calling into a proprietary binary which will do the computation on a GPU or something like that).

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @11:13AM (#28888410)
> I don't think it's that simple. You need a way to differentiate code that runs at compile time and code that runs at runtime (because at compile time you can afford a "slow" algorithm, while at run-time you'll be calling into a proprietary binary which will do the computation on a GPU or something like that).

You mean std::is_constant_evaluated()? You don't need constexpr to be able to have that.

Re:Proposal to add constexpr to C [pdf] by jcelerier on Saturday October 16, 2021 @11:33AM (#28888554)
but how will you differentiate a call that you want to perform at compile-time vs at run-time? e.g. if you want to run some unit tests to check the two algos, today you'd do:

    int res = my_algo();
    CHECK(res == 123);
    ...
    constexpr int res = my_algo(); 
    CHECK(res == 123); // compile-time version is the same
with

    int my_algo() { 
      if constexpr(is_constant_evaluated()) { 
        return 123;
      else
        return some_lib->very_advanced_computation();
    }
how do you do the same without the constexpr keyword ? i'd rather not introduce a template struct just to get a constexpr context, à la

    template<auto Value>
    struct manually_constexpr { static constexpr auto value = Value; };

    CHECK(manually_constexpr<my_algo()>::value == 123);
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @02:40PM (#28890270)
> but how will you differentiate a call that you want to perform at compile-time vs at run-time?

You could never do that to begin with. The compiler was always free to evaluate your function at compile time (and already did so in some cases).

> e.g. if you want to run some unit tests to check the two algos

Just make two separate functions and compare their outputs. That's what functions are for! So you don't put everything in one giant block of code.

> i'd rather not introduce a template struct just to get a constexpr context, à la

The standard library could do that for you instead of introducing a new keyword. In fact it practically already did so with std::integral_constant; they just need to update it for C++20 to avoid the redundancy.

Or they could've introduced a [[pure]] attribute, or other less intrusive mechanisms. The keyword wasn't necessary for anything you mentioned.

Also, as the sibling comment said, you might want to check out consteval.

Re:Proposal to add constexpr to C [pdf] by jcelerier on Saturday October 16, 2021 @03:57PM (#28890926)
> You could never do that to begin with. The compiler was always free to evaluate your function at compile time (and already did so in some cases).

no, that is false. the constant expression context is specified by the standard - the following will always hold if your compiler is not braindead : https://gcc.godbolt.org/z/zEEbWbhvr

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @04:02PM (#28890969)
>> You could never do that to begin with. The compiler was always free to evaluate your function at compile time (and already did so in some cases).

> no, that is false.

Your sentence is false, not mine. See below.

> the constant expression context is specified by the standard

Expressions can be evaluated at compile-time outside of "constant expression contexts", under the as-if rule. That's one of the main things compilers do when optimizing code.

Re:Proposal to add constexpr to C [pdf] by jcelerier on Saturday October 16, 2021 @04:10PM (#28891029)
> Expressions can be evaluated at compile-time outside of "constant expression contexts", under the as-if rule.

yes, but that does not make it a constexpr context, which is something explicitely specified by the standard. See my code example: the compiler is obviously able to evaluate foo() at compile time, yet it knows that the evaluation it does at compile time will yield a different result that the one it does in a constexpr context.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @04:19PM (#28891110)
> yes, but that does not make it a constexpr context

It seems like we're talking past each other here. You wrote

"How will you differentiate a call that you want to perform at compile-time vs at run-time [without constexpr]?"

And I've been replying to that by pointing out that your run-time code can still be evaluated at compile time even if you don't use constexpr. Heck, I'll point out now that it can still be evaluated at run-time even if you do use constexpr! [1] It's neither here nor there.

Now you're talking about whether "constexpr contexts" do this, which is a separate question. Incidentally, even constexpr contexts don't distinguish between compile-time and run-time evaluation in anywhere except the condition itself [1], which is not the part you generally care the most about. If you want compile-time evaluation, you need to force its evaluation at a location where it's required to be evaluated at compile time, which is either a template parameter or a constexpr variable declaration.

You seem to be desiring consteval when you talk about constexpr.

(And you still haven't addressed the fact that your unit-test example is better served by having two separate functions!)

> the compiler is obviously able to evaluate foo() at compile time, yet it knows that the evaluation it does at compile time will yield a different result that the one it does in a constexpr context.

Citing this ability as if it's desirable is really strange. If your code does that it's buggy. A good language would outlaw this, not embrace it.

[1] https://gcc.godbolt.org/z/Yhqvqz5Pc

Re:Proposal to add constexpr to C [pdf] by jcelerier on Saturday October 16, 2021 @04:48PM (#28891369)
> "How will you differentiate a call that you want to perform at compile-time vs at run-time [without constexpr]?"

right, I should have wrote "in a constexpr context", e.g. what you find in template<invocations>, etc.

> And I've been replying to that by pointing out that your run-time code can still be evaluated at compile time even if you don't use constexpr.

I don't understand what this does have to do with the rest. That's just an optimization (which is not "consistently observable" and depends on the whims of the compiler). Making a variable constepxr is something that causes consistently observable results, which is much more useful. Incidentally, I have had multiple cases where things that could obviously be computed at compile-time weren't optimized in such a way by clang or gcc unless I did

    constexpr auto foo() { constexpr auto bar = some_complicated_function(...); return bar; }
instead of

    constexpr auto foo() { return some_complicated_function(...); }
with constexpr, if the compiler cannot compute the thing at compile time I get an error (which is good !)

> You seem to be desiring consteval when you talk about constexpr.

what I actually desire deep down is a way to have aribtrary parametrisable contexts, something like a generalized version of http://www.jot.fm/issues/issue_2008_03/article4/ ; having two is already a good start.

> (And you still haven't addressed the fact that your unit-test example is better served by having two separate functions!)

well, because I disagree. If the name my function is e.g. strlen I definitely don't want a strlen_constexpr and strlen_nonconstexpr pair of functions, I want the good choice to be made depending on the context I'm in ; I want to write "strlen" in generic code and have the correct thing happen no matter what.

to give you my general perspective, constexpr could call itself super_bamboozle that I couldn't care less, I just want "multiple worlds" being available in my programming language. what name they take is of very little importance.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @04:54PM (#28891408)
> what I actually desire is a way to have aribtrary parametrisable contexts, something like a generalized version of http://www.jot.fm/issues/issue_2008_03/article4/ ; having two is already a good start.

I actually wholeheartedly agree with that. I've wanted something pretty similar for a long time. I just also wholeheartedly disagree on constexpr having been a good start on that.

> Incidentally, I have had multiple cases where things that could obviously be computed at compile-time weren't optimized in such a way by clang or gcc unless I did [...]

And this is one place we circle back to my argument, which is that implicit constexpr should be the default wherever possible. That way you don't e.g. run into situations where you forgot the keyword by accident, because you won't need it to begin with.

> well, because I disagree. If the name my function is e.g. strlen I definitely don't want a strlen_constexpr and strlen_nonconstexpr pair of functions, I want the good choice to be made depending on the context I'm in ; I want to write "strlen" in generic code and have the correct thing happen no matter what.

I think you misunderstood the proposal then. I was saying those functions would be only called directly for tests. Everywhere else, you'd use your strlen() with std::is_constant_evaluated() (or whatever) dispatching to one of those two functions, which would be implementation details hidden away from the user.

Re:Proposal to add constexpr to C [pdf] by petters on Saturday October 16, 2021 @02:07PM (#28889959)
"constexpr" does not do what you think it does.

For example, "if constexpr(is_constant_evaluated())" is always true, I think.

See also the new C++ keyword "consteval" (yes, really!)

Re:Proposal to add constexpr to C [pdf] by jcelerier on Saturday October 16, 2021 @04:01PM (#28890963)
ah yes, that'll teach me to type on my phone :)

what do you think that I think that constexpr does ? constexpr in a variable forces the variable's value to be evaluated in a constant expression context (which comes with footgunes, see an in-depth coverage of the issue there: https://gist.github.com/Som1Lse/5309b114accc086d24b842fd803b...)

Re:Proposal to add constexpr to C [pdf] by secondcoming on Saturday October 16, 2021 @06:20AM (#28886812)
Is it superfluous? I will admit that when I first read about constexpr my first thought was 'why can't the compiler figure this out automatically?'. I assume that compiler vendors all agreed that a new keyword was necessary, they don't add them without reason.
Re:Proposal to add constexpr to C [pdf] by nuerow on Saturday October 16, 2021 @07:11AM (#28887055)
> I will admit that when I first read about constexpr my first thought was 'why can't the compiler figure this out automatically?'.

I would argue that the main value proposition of constexpr is not what the compiler can figure out automatically but allowing the developer to express where he wants constexpr and afterwards allow the compiler to verify if that's possible.

It's the difference between a soft "nice-to-have" requirements and a hard "must-have" requirement.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @11:26AM (#28888505)
> I would argue that the main value proposition of constexpr is not what the compiler can figure out automatically but allowing the developer to express where he wants constexpr and afterwards allow the compiler to verify if that's possible.

If you want to look at it that way, it only applies to variable declarations at best. Not function declarations, which is the most common case of where it's used (and it completely clutters the code).

And honestly, if that was the value proposition, they could've just done it a million other ways. Like think even 'template<auto V> static const auto constant = V' would let you do constant<whatever> and verify it at compile time. Yeah it's C++20 but they could've still done it then or used a different approach, there are lots of ways to address this (attributes, etc.). No need to clutter every function prototype in the language for something that small.

Also I think you're thinking more of consteval than constexpr.

Re:Proposal to add constexpr to C [pdf] by nuerow on Saturday October 16, 2021 @01:33PM (#28889607)
> If you want to look at it that way, it only applies to variable declarations at best. Not function declarations, which is the most common case of where it's used (and it completely clutters the code).

Not really. The whole point of constexpr is to state that an expression is constant, thus the value returned by the function is computed at compile time.

> And honestly, if that was the value proposition, they could've just done it a million other ways.

To me it seems thay annotating a function with constexpr is the clearest and most straight-forward way to go about expressing constant expressions.

> Also I think you're thinking more of consteval than constexpr.

To each his own, but if the whole point is to represent constant expressions then the constexpr keyword seems to be straight-forward.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @02:53PM (#28890373)
> Not really. The whole point of constexpr is to state that an expression is constant, thus the value returned by the function is computed at compile time.

That's not even one point of constexpr, let alone the whole point. Putting constexpr in front of a function declaration does absolutely nothing to the codegen. See for yourself: https://gcc.godbolt.org/z/34h6Tanzn

Notice that both h() and f() are called despite being constexpr.

> To me it seems thay annotating a function with constexpr is the clearest and most straight-forward way to go about expressing constant expressions.

Again, it doesn't do what you think (see above). It does absolutely nothing to a function.

> To each his own, but if the whole point is to represent constant expressions then the constexpr keyword seems to be straight-forward.

This isn't an opinion thing. The consteval literally does what you're imagining constexpr does. Just replace constexpr with consteval in the code above. (I could probably argue that one has little use too, but that's not what I'm arguing here.)

Re:Proposal to add constexpr to C [pdf] by thezilch on Saturday October 16, 2021 @03:47PM (#28890847)
Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @03:59PM (#28890939)
You're seeing the compiler opportunistically make an optimization by taking constexpr as an extra inlining hint. I showed you it's not something you can rely on in my example. You have to realize constexpr only talks about what is allowed to happen, not what is guaranteed to happen. You want consteval for that.
Re:Proposal to add constexpr to C [pdf] by thezilch on Saturday October 16, 2021 @04:26PM (#28891167)
Of course I want consteval, if a later C++ is available to me, but that doesn't excuse you writing constexpr does absolutely nothing, when it clearly does. It's no surprise your example doesn't fold calls without `-O3` or that one could produce a `constexpr` that doesn't fold to a constant (go ahead and try though :>).

But consteval function is also not a literal replacement constexpr. For example, you can't take a pointer to the former. There's a reason they co-exist and are not useless.

Re:Proposal to add constexpr to C [pdf] by dataflow on Saturday October 16, 2021 @04:35PM (#28891241)
> Of course I want consteval, if a later C++ is available to me, but that doesn't excuse you writing constexpr does absolutely nothing, when it clearly does.

consteval wasn't intended to be excusing anything. I was just letting you know you're misunderstanding what constexpr does, and that what you're thinking it's supposed to do is in fact consteval's job.

You seem very confused about language specifications. That GCC and Clang happen to interpret constexpr as an extra "please inline" hint under -O3 is not evidence of constexpr "doing" something, and certainly not justification for including it in the language standard. That's like saying HN's orange color is "doing something" just because you really like to go eat an orange every time you see it.

I suspect you will have a hard time finding any evidence that constexpr was ever intended to be a "this is technically optional but please really, really try to inline this" hint of sorts to the compiler by the committee.

> But consteval function is also not a literal replacement constexpr.

I didn't say it was.

> For example, you can't take a pointer to the former.

"Therefore constexpr is useful" does not follow from this.

> There's a reason they co-exist and are not useless.

There's a mediocre reason for consteval, and a bad reason for constexpr. The former is probably unnecessary IMO though still of marginal utility, and in any case I can concede there's a debate that could be had there. The latter would be practically useless if the language cared to just make it the implicit default. It's really only solving a problem it created.

If you're using constexpr as an "optional but highly recommended inline" hint like you're showing me in your examples, you're doing the equivalent of pulling up HN's orange color so it coaxes you (or someone else) to go eat an orange. You are certainly welcome do that (hopefully it's a free country where you live) and I'm not stopping you per se, but it's missing both the letter and the spirit of the keyword(/color) by a colossal margin.

Re:Proposal to add constexpr to C [pdf] by rowanG077 on Saturday October 16, 2021 @07:53AM (#28887202)
The compiler can figure it out. But that doesn't solve the problem constexpr was created for. Without constexpr compile time evaluation becomes very brittle. Constexpr is there to help the compiler and developer reach an understanding of the stuff that has to be evaluated at compile time.
Re:Proposal to add constexpr to C [pdf] by atq2119 on Sunday October 17, 2021 @05:30AM (#28895123)
The problem is that (especially library) code just becomes absolutely littered with constexpr, because realistically speaking, you do want everything that can be constexpr to actually be constexpr.
Re:Proposal to add constexpr to C [pdf] by rowanG077 on Sunday October 17, 2021 @06:07AM (#28895293)
Why is that a problem? I actually really like seeing if a library function can be cte'd.
Re:Proposal to add constexpr to C [pdf] by dataflow on Sunday October 17, 2021 @03:16PM (#28898943)
> Why is that a problem?

Because whether a call should be CTE'd is a decision for the caller to make, not the callee.

> I actually really like seeing if a library function can be cte'd.

That's not what you're seeing with constexpr. It's what you're seeing with consteval. [1]

What you're seeing with constexpr is which functions are prohibited from being CTE'd. Which is pretty useless when you don't intend to CTE them in the first place, and actively counterproductive when you do.

[1] Actually this is kind of a lie too [2], but at least it's much closer to the truth.

[2] Notice that seeing consteval here tells you absolutely nothing: https://gcc.godbolt.org/z/bWzd4v6Y1

Re:Proposal to add constexpr to C [pdf] by rowanG077 on Monday October 18, 2021 @08:05AM (#28904551)
consteval says it MUST be constant evaluated not that it CAN be constant evaluated. That is very different. With consteval it's not up to the caller to make the decision of whether to run at compile-time or not, the caller must provide constexpr arguments. With just a constexpr annotation the caller can decide to run it either at compile-time or run-time.

See this code:

https://godbolt.org/z/oMWKcWW5e

Re:Proposal to add constexpr to C [pdf] by dataflow on Monday October 18, 2021 @08:09AM (#28904578)
Like I said:

>> [1] Actually this is kind of a lie too [2], but at least it's much closer to the truth.

>> [2] Notice that seeing consteval here tells you absolutely nothing: https://gcc.godbolt.org/z/bWzd4v6Y1

Note I didn't claim this was their only difference.

Re:Proposal to add constexpr to C [pdf] by rowanG077 on Monday October 18, 2021 @08:29AM (#28904698)
I don't see what's your problem with libraries marking their functions as constexpr then. The library says it's up to the caller to decide whether this function is constant evaluated. Precisely what you wanted. If libraries start marking their function as consteval. Now that would be a problem.
Re:Proposal to add constexpr to C [pdf] by dataflow on Monday October 18, 2021 @08:33AM (#28904722)
> I don't see what's your problem with libraries marking their functions as constexpr then. The library says it's up to the caller to decide whether this function is constant evaluated.

The problem was explained here: https://news.ycombinator.com/item?id=28895123

The language could just say everything that could be constexpr is implicitly constexpr, and you'd get just as useful of an effect (even on existing code!) without anyone having to do anything extra. It's very rare for a function that could be constexpr to be justifiably prohibited from being used as such, and they could've introduced an opt-out attribute for that if they really cared.

Re:Proposal to add constexpr to C [pdf] by rowanG077 on Monday October 18, 2021 @08:53AM (#28904898)
You are going in circles...

constexpr is an interface guarantee. If it were not there the entire optimization stack would become brittle. Imagine updating a dependency or rewriting a function and suddenly your program is 10x slower. Things like this are known in other languages. For example Haskell and fusion optimization. It's fine for you to disagree with this reasoning. But then you should not be using C++ as you don't really care for performance and can use many other better suited languages.

Then you say constexpr doesn't make it possible for the caller to specify whether something is cte'd while this is precisely what the caller decides. You are confusing constexpr and consteval. consteval doesn't make it possible for the caller to decide whether the function is cte'd.

Please answer the points I have brought up instead of simply referring to something I have already refuted.

Re:Proposal to add constexpr to C [pdf] by dataflow on Monday October 18, 2021 @08:59AM (#28904951)
> Imagine updating a dependency or rewriting a function and suddenly your program is 10x slower.

That can already happen and will still be possible after constexpr. And it was always preventable by forcing evaluation of the variable in a CTE context, like in std::integral_constant. And you're missing the fact that an implicit constexpr with an explicit opt-out needn't behave any differently from one with explicit opt-in. Same semantics, just fewer keystrokes.

> constexpr is an interface guarantee

> Please answer the points I have brought up instead of simply referring to something I have already refuted.

You didn't actually refute it (though you tried), and I already did address them:

>> [2] Notice that seeing consteval here tells you absolutely nothing: https://gcc.godbolt.org/z/bWzd4v6Y1

Replace consteval with constexpr and you'll see it told you absolutely nothing about bar()'s CTE'ability. Observe how the callee used constexpr and bar() failed to CTE despite being constexpr: https://gcc.godbolt.org/z/odqbT7x9j

> You are going in circles...

Because you went in circles. I've directly addressed every single one of your points but then you looped back to ask the same question as you did in the beginning. Same questions, same answers.

Re:Proposal to add constexpr to C [pdf] by rowanG077 on Monday October 18, 2021 @09:21AM (#28905165)
> [2] Notice that seeing consteval here tells you absolutely nothing: https://gcc.godbolt.org/z/bWzd4v6Y1

In that example marking bar as consteval does nothing. Because you are not ever calling bar... Calling bar shows that it's not possible because foo is not constexpr:

  note: non-constexpr function 'foo<int>' cannot be used in a constant expression
  consteval T bar(T x) { return foo(x); }
Marking foo as constexpr makes it compile and compile time evaluate both foo and bar.

> Replace consteval with constexpr and you'll see it told you absolutely nothing about bar()'s CTE'ability. Observe how the callee used constexpr and bar() failed to CTE despite being constexpr: https://gcc.godbolt.org/z/odqbT7x9j

It doesn't compile because foo is not constexpr. Marking foo as constexpr makes it compile and foo and bar are evaluated at compile time. It produces this ASM:

  main:                                   # @main
          pushq   %rbp
          movq    %rsp, %rbp
          movl    $0, -4(%rbp)
          movl    $0, -8(%rbp)
          xorl    %eax, %eax
          popq    %rbp
          retq
At least try to the examples you are using to make your point. Because they in fact show that you are wrong...
Re:Proposal to add constexpr to C [pdf] by dataflow on Monday October 18, 2021 @09:55AM (#28905467)
The examples are not wrong, you're just not understanding them.

> It doesn't compile because foo is not constexpr.

Well obviously. That's not the question here. The question is, explain to me exactly what guarantee the declaring bar() as 'constexpr' achieved for anyone? It clearly didn't prevent its author from calling a non constexpr function, and it clearly didn't signal to its users that it is usable from a constexpr context either. The user had to go inspect each one of its callees manually to see if they could all be evaluated at compile time in reality, which is exactly what you just did with foo(). Which is pretty damn hard (as in, Turing-undecidably-hard) when things are templates and you have ADL on top of that. And which the presence of constexpr on bar() didn't help you one bit with.

The declaration of bar() told you exactly nothing by having constexpr in it. It made no difference whatsoever for itself, nor for main(). It just added clutter.

Re:Proposal to add constexpr to C [pdf] by rowanG077 on Monday October 18, 2021 @10:33AM (#28905818)
The code doesn't compile, so it did in fact stop the author from calling a non-constexpr function from a constexpr function. You can't meaningfully semantically talk about code that doesn't compile.
Re:Proposal to add constexpr to C [pdf] by dataflow on Monday October 18, 2021 @01:07PM (#28907831)
> You can't meaningfully semantically talk about code that doesn't compile.

You can point out that it failed to compile, and that can be a benefit when compiling would've been detrimental. Just like you yourself literally just did when you said "The code doesn't compile [...]".

> it did in fact stop the author from calling a non-constexpr function from a constexpr function.

The constexpr in front of bar() is not what prevented compilation. You don't believe me? Just take it out and see. The code would've failed to compile the exact same way without constexpr in front of bar(). Try it before disagreeing with me.

You're saying putting constexpr in front of bar() has a benefit. I'm saying: tell me what it was. Making that constexpr be always in front of bar() implicitly would've resulted in exactly the same outcome in every situation where the code compiles and also where it fails to compile (like above). Nothing would've been any different. I don't get why this is so difficult but I'm not going to keep repeating myself. Everything I can possibly imagine explaining is in my comments up to this point so just re-read them, I have no other way I can phrase these. Everyone else has understood what I'm saying and I'm at a loss how else to explain it differently. I promise you it's not wrong, we're just failing to communicate.

Re:Proposal to add constexpr to C [pdf] by pjmlp on Saturday October 16, 2021 @06:27AM (#28886861)
It can, check the C++ compiler Circle.

https://www.circle-lang.org

Unfortunately it isn't a direction WG21 is willing to adopt.

Re:Proposal to add constexpr to C [pdf] by wtetzner on Saturday October 16, 2021 @09:49AM (#28887865)
I just assumed the constexpr keyword was added to help the programmer ensure that what they were writing could be run at compile time.