Live data from Hacker News

C++17 constexpr everything, or as much as the compiler can

solarianprogrammer.com

81–90 of 120 posts

Re: C++17 constexpr everything, or as much as the compiler can

#81

D doesn't need constexpr. It's much simpler - any function whose value is needed at compile time is evaluated at compile time. For example: int square(int x) { return x * x; } const y = square(3); // evaluated at compile time int bar() { int[square(2)] array; // evaluated at compile time return square(3); // evaluated at run time } If a value is needed at compile time, and the function cannot be evaluated at compiler…

I think this might waste resources for some transient results. Sometimes that computation time required for evaluation is negligible, and the result might require more memory than "the function call".

Re: C++17 constexpr everything, or as much as the compiler can

#82

Earlier quoted context omitted.

> It ensures that the variable could be evaluated at compile time Why couldn't a variable without constexpr be evaluated at compile-time? Nobody ever explains this.

The option was discussed during standardization. It is expected that some corners of the language will never be available at compile time, for example I/O. So you need a keyword to declare a function to be callable a compile time, otherwise its constexpressness would depend on its implementation details and wouldn't be possible to check it in isolation. It might not be a great reason (some code becomes a keyword soup…

> It is expected that some corners of the language will never be available at compile time, for example I/O.

So you're saying functions that have side-effects like I/O can actually perform those operations at compile-time if marked with constexpr?

Re: C++17 constexpr everything, or as much as the compiler can

#83

Earlier quoted context omitted.

Certain things, when used in a routine, make computation impossible at compile time. If the routine is marked with 'constexpr', the compiler will verify that.

Couldn't it already do the exact same thing without constexpr? (And shouldn't it have already done that when optimizing? In fact for simpler expressions compilers already do this, right?) How does specifying constexpr help?

But I think you nailed it -- the compiler doesn't have to signal optimization "failures" back to the developer, but it has to for the constexpr case. It is not that the constexpr routine can be used at compile time, it is that it must be useable at compile time.

Re: C++17 constexpr everything, or as much as the compiler can

#84

Earlier quoted context omitted.

Couldn't it already do the exact same thing without constexpr? (And shouldn't it have already done that when optimizing? In fact for simpler expressions compilers already do this, right?) How does specifying constexpr help?

But I think you nailed it -- the compiler doesn't have to signal optimization "failures" back to the developer, but it has to for the constexpr case. It is not that the constexpr routine can be used at compile time, it is that it must be useable at compile time.

> But I think you nailed it -- the compiler doesn't have to signal optimization "failures" back to the developer, but it has to for the constexpr case.

Is this true? Where do you see Clang emit a diagnostic in the example in the given article? (https://godbolt.org/g/HKcPFT)

Re: C++17 constexpr everything, or as much as the compiler can

#85

D doesn't need constexpr. It's much simpler - any function whose value is needed at compile time is evaluated at compile time. For example: int square(int x) { return x * x; } const y = square(3); // evaluated at compile time int bar() { int[square(2)] array; // evaluated at compile time return square(3); // evaluated at run time } If a value is needed at compile time, and the function cannot be evaluated at compiler…

What about values that aren't needed at compile time, but can be so optimized.

D still has optimization passes.

Re: C++17 constexpr everything, or as much as the compiler can

#86

D doesn't need constexpr. It's much simpler - any function whose value is needed at compile time is evaluated at compile time. For example: int square(int x) { return x * x; } const y = square(3); // evaluated at compile time int bar() { int[square(2)] array; // evaluated at compile time return square(3); // evaluated at run time } If a value is needed at compile time, and the function cannot be evaluated at compiler…

Maybe 'constexpr' has been added rather to express the intent (for example, for library development)?

You can annotate D functions as 'pure', which would have that effect, but purity is used for other reasons.

Evaluating functions at compile time has another wrinkle in D - it is path dependent:

    int square(int x) {
        if (x 
I.e. the path taken through the function has to be pure, not every part of the function.

Re: C++17 constexpr everything, or as much as the compiler can

#87

D doesn't need constexpr. It's much simpler - any function whose value is needed at compile time is evaluated at compile time. For example: int square(int x) { return x * x; } const y = square(3); // evaluated at compile time int bar() { int[square(2)] array; // evaluated at compile time return square(3); // evaluated at run time } If a value is needed at compile time, and the function cannot be evaluated at compiler…

I think this might waste resources for some transient results. Sometimes that computation time required for evaluation is negligible, and the result might require more memory than "the function call".

It's been in D for a decade, and has been extremely successful, to the extent of becoming a critical feature.

An early example was someone wrote a ray tracer in D that ran and generated output completely at compile time.

A more useful example is D's regex package can build the engine at compile time, thereby emitting a custom engine for the regex, instead of at runtime.

Re: C++17 constexpr everything, or as much as the compiler can

#88

Earlier quoted context omitted.

There's precedent in C++ for keywords that give the compiler hints it doesn't necessarily promise to act on: inline.

Happy to be corrected (EDIT: indeed, I stand corrected! see replies below), but I don't think the C++ spec says anything about 'inline' encouraging the compiler to inline the compiled code? 'auto' would've been an example, but that also got removed, because they realized it was useless. I don't get how constexpr is any different.

I don't know my way around the spec, but Wikipedia is pretty unequivocal:

"... it serves as a compiler directive that suggests (but does not require) that the compiler substitute the body of the function inline by performing inline expansion, i.e. by inserting the function code at the address of each function call, thereby saving the overhead of a function call."

https://en.wikipedia.org/wiki/Inline_function

Re: C++17 constexpr everything, or as much as the compiler can

#89

Earlier quoted context omitted.

Happy to be corrected (EDIT: indeed, I stand corrected! see replies below), but I don't think the C++ spec says anything about 'inline' encouraging the compiler to inline the compiled code? 'auto' would've been an example, but that also got removed, because they realized it was useless. I don't get how constexpr is any different.

I don't know my way around the spec, but Wikipedia is pretty unequivocal: "... it serves as a compiler directive that suggests (but does not require) that the compiler substitute the body of the function inline by performing inline expansion, i.e. by inserting the function code at the address of each function call, thereby saving the overhead of a function call." https://en.wikipedia.org/wiki/Inline_function

Thanks for this! I was very skeptical, but you made me look through every single mention of the word 'inline' in the spec, and you are indeed correct. :) Here is the relevant quote:

> [7.1.2] [dcl.fct.spec] A function declaration with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by shall still be respected

Re: C++17 constexpr everything, or as much as the compiler can

#90

Earlier quoted context omitted.

But I think you nailed it -- the compiler doesn't have to signal optimization "failures" back to the developer, but it has to for the constexpr case. It is not that the constexpr routine can be used at compile time, it is that it must be useable at compile time.

> But I think you nailed it -- the compiler doesn't have to signal optimization "failures" back to the developer, but it has to for the constexpr case. Is this true? Where do you see Clang emit a diagnostic in the example in the given article? ( https://godbolt.org/g/HKcPFT )

You seem to be right -- at least "no diagnostics required" is mentioned a few times in $10.1.5 of N4700. To be honest, my comment is not from the article in the example, but from my own experience, and that is mostly with GCC 7.2.
Post reply on HN