Namespaces
Variants
Views
Actions

Talk:cpp/language/constexpr

From cppreference.com

Maybe it is useful to say "pointer addresses" are known no sooner than at "linker time". Regardless, there is possible to use "poniters" indirectly in "constexpr", where "constexpr" are values known at "compile time". See Stroustrup's book "The C++ Programming language 4th edition" page 267.

 constexpr const char *p1 = "asdf";
 constexpr char c = p1[2];  // c=='d', the compiler knows the value pointed to by "p1"

I saw these lines on the web publicly available. --vlakov 08:00, 4 May 2014 (PDT)


that chapter in the book talks about address constant expressions, they are mentioned on this wiki at the bottom of cpp/language/constant_expression. I agree that the constexpr page here needs some careful attention, though. --Cubbi (talk) 12:25, 4 May 2014 (PDT)
Sorry, I didn't see it. It is too formal for me (I am a mere mortal). I confess without an example I wouldn't know what it is :-). --vlakov 193.58.194.195 02:45, 5 May 2014 (PDT)

Contents

[edit] constexpr function part > C++14 is missing function call restriction

I don't know where the information on C++14 come from and if you have to use the wordings from the standard when editing the site, so I didn't do that directly. I hope someone reads this and corrects the page.

What I mean with "missing function call restriction" in the title is that in the box describing which restrictions constexpr functions have since C++14, there is no word about the fact that constexpr functions can not call non-constexpr functions (which must stay true in every subsequent C++ standard if I understand this stuff correctly). This should probably be added above the "until C++14" and "since C++14" boxes, although – strictly speaking – the information is only missing for the "since C++14" part, because in the other one it is part of the last statement ("exactly one return statement that contains only literal values, constexpr variables and functions.").

[edit] constexpr function part > C++14 is missing function call restriction

Sorry, forgot to sign my post :S

Here is my signature:

JP wanN (talk) 18:38, 16 July 2014 (PDT)

Actually constexpr functions don't need to produce constant experssions for all possible arguments, as long as it can do so for at least one possible input. For example, the following function definition is legal, even though it will call the non-constexpr constructor of std::range_error when the argument is negative.

constexpr int factorial(int n)
{
    return n < 0 ? throw std::range_error("")
            : n == 0 ? 1
             : (n * factorial(n-1));
}

Anyway, this page does need some notes for that. Thank you. --D41D8CD98F (talk) 07:58, 17 July 2014 (PDT)

[edit] Using the Standard Library in constexpr Functions

IMHO it could be helpful to add some guidance which part(s) of the stdlib may be used in constexpr functions, especially if this could be done in a brief way, based on header files. (Or have I missed a hint on that on my cursory glance over the page?)

AFAIK all mathemathical functions (from <cmath>) are OK, but what else? Surely nothing from <iostream>, <thread>, but <array> looks as if it should cause no problems. What about <algorithm>s (eg. sort on an array) ...

Mwe (talk) 11:20, 29 June 2015 (PDT)

Functions in the standard library are either constexpr (like std::array::operator[]) or they aren't (like std::sqrt). It is specified on each function's own page. Non-constexpr functions can't be called on the constexpr path example --Cubbi (talk) 12:07, 29 June 2015 (PDT)

OK ... I see, so it's not that simple that it can be decided by header file.

Related (2nd) question: is there (maybe) an easy way to extract all constexpr functions from the C++11/14 standard? I remember that after C89 was published, on my request in comp.lang.c someone[*] provided me with a machine readable list of all library functions including the signature (agreed: C89 had a MUCH small stdlib than C++14).

[*: to give credit where credit due: that helpful someone about a quarter century ago was Chris Torek ... no idea what he is doing today]

Mwe (talk) 13:46, 29 June 2015 (PDT)

I suppose you could try parsing the source text of the standard, e.g. above-mentioned std::array::operator[] is found in containers.tex line 2649. I don't know of a better way. --Cubbi (talk) 14:17, 29 June 2015 (PDT)

Thank you - I did a short research too but nothing really (and immediately) useful turned up, like e.g. a CSV file (or maybe even XML to be easily parsed with XSLT). As such a machine readable list might be useful to do many sorts of things (not only wrt constexpr) I wonder why there is none somewhere in the internet.

Anyway thanks. Mwe (talk) 22:58, 29 June 2015 (PDT)

[edit] noexcept -> constant expression is not true always!

The following note is not completely correct, IIRC: "Because the noexcept operator always returns true for a constant expression, it can be used to check if a particular invocation of a constexpr function takes the constant expression branch:". As noted in "Limitations" here: http://stackoverflow.com/a/13305072 , noexcept returns false for things like "(0 ? throw "fooled!" : 42)" 91.2.77.198 08:57, 1 January 2016 (PST)

Hmm, CWG 1351 changed the rules, and this should now return true, making the statement correct as written. We haven't merged it as a DR yet elsewhere, though. T. Canens (talk) 10:15, 1 January 2016 (PST)
Thanks for the reference to the DR. That's a lot to read today :) Please feel free to fix the referenced answer if you like. 91.2.65.242 00:38, 4 January 2016 (PST)

[edit] "(for constructors, use in a constant initializer is sufficient) (since C++14)" is misplaced within "constexpr function"

The note "(for constructors, use in a constant initializer is sufficient) (since C++14)" and associated text that applies to constructors should be put within "constexpr constructor". A constexpr function is never a constructor, so the statement "for constructors, ..." within the clarification of term "constexpr function" is incorrect, as it makes the readers think all the other bullets within there also apply to constexpr constructors, which is not true. 79.218.74.61 08:43, 29 July 2017 (PDT)

[edit] Non Literal (but unused) parameters to constexpr functions

At the current time, all parameters to constexpr functions must be Literal. It seems to me that parameters that are not used by the function body should not have to meet this restriction. Unused parameters can be included for a number of reasons, including differentiation between function overloads. Ignoring things like promotion of short to int, here are examples, very much simplified:

   (1) constexpr std::string_view type_name(bool value) { return "bool" }
   (2) constexpr std::string_view type_name(int value) { return "int" }
   (3) constexpr std::string_view type_name(double value) { return "double" }
   (4) constexpr std::string_view type_name(long double value) { return "long double" }

One might expect to be able to extend this further:

   (5) constexpr std::string_view type_name(std::string value) { return "string" }

but that fails because std::string can't be a Literal value. Luckily, references are Literal so the following does work:

   (6) constexpr std::string_view type_name(std::string &value) { return "string" }

Add a template and things get more complicated:

   (7) constexpr std::string_view type_name(T value) {
           if std::is_enum_v<T> return "enum"sv;
           if std::is_integral_v<T> return "some other integral type"sv;
           if std::is_floating_point_v<T> return "some other floating type"sv;
           return "something else not yet implemented"
       }

The template CAN be used with a what appears to be non-Literal type because it actually matches with T being a reference (such as "std::map<...> &").

Anyway, my suggestion for improvement is that if the parameter is anonymous (e.g., "std:string" instead of "std:string value") then that parameter should not keep the function from being declared constexpr. Anonymous parameters don't prevent a function from being executed at compile time!

(If you wanted to take this reasoning further, then any parameters that are not used anywhere inside a function's body, anonymous or named, should not keep that function from being declared constexpr.)

Having laid this long groundwork, does my reasoning make sense to others? Should a change be proposed the C++ standard committee for some future revision?

172.88.122.95 16:21, 10 January 2022 (PST)

That non-trivial std::string (which is actually allowed in C++20) still needs its destructor executed, so it doesn't quite have no effect on the function, and I would generally advise that you don't add useless parameters to your functions if they really are useless --Ybab321 (talk) 04:41, 11 January 2022 (PST)

[edit] Proposal: constexpr-deduction

If you want a big performance boost for C++ applications then please consider supporting my proposal for constexpr-deducibility.

  • ammend variable statements with constexpr-specification if their initialization is constexpr!
  • turn whole structs into constexpr if their initialization is constexpr
  • turn single struct members constexpr with special "constexpr(auto)" specifier
  • manual constexpr speicification based on compile-time boolean condition "constexpr(enable)"
  • code-gen of functions specialized for constexpr-profiles, improving performance based on the special circumstance of each function-invocation!
  • save program memory by removing variables from program memory by turning them constexpr, purely automatic!
  • improve performance of legacy applications by enabling constexpr-deducibility at language-design-time, shifting a lot of program code-graphs into compile-time!

https://osdn.net/projects/magic-txd/forums/33389/44440/#forum-message-93256

Quiret (talk) 04:42, 6 January 2023 (PST)

It's been proposed and rejected before. One the big points of specifying constexpr is precisely that it's not deduced, it's enforced, and the compiler will helpfully tell you that you've violated constexpr eligibility if you haven't met the requirements; and if you don't specify constexpr, then users of your API won't rely on being able to write constexpr code that uses that API, if constexpr was deduced, then an update to your code that causes constexpr to not be deduced will break users of the API's code that relied on that (for example, if I wrote constexpr uint32_t new_val = ROL(val, cnt); and used that as the size of an array, then later I needed to change val to be read from argv, then damn my code explodes, I sure wish I didn't rely on that constexprness when I wrote that array...). This is the main reason why stdlib vendors can't arbitrarily add constexpr to stdlib functions; P1235 does actually address this, but was considered unstomachable (for reasons known only to those with access to the clandestine EDG wiki). There's also the issue that constexpr implies inline, which is often not desirable (increased build times, can't separate declaration and definition into header and source files). --Ybab321 (talk) 08:34, 6 January 2023 (PST)
You are trying to use bad software design decisions as argument against implicit-constexpr while completely ignoring the benefits. Sorry, but I disagree with you on every point. Don't be held back by bad examples: lead the charge into a good future with good examples! Of course bad software developers exist! But they don't exist because of constexpr-misuse! When this was voted upon in 2019, compiler vendors had an incomplete idea about what constexpr meant for C++ development. The benefit of allowing constexpr functions to be tied into the compiler's optimization strategy is a key benefit of implicit constexpr. Implicit constexpr is unit-testable if the compiler vendors have a good compiler implementation. Just be honest: the true reason of rejection is risk-scare on the compiler vendor's side. Every reasonable dev would love to have the ability for constexpr-deduction! Here is an example of valor by the GCC compiler: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=87c2080b Quiret (talk) 00:30, 8 January 2023 (PST)
Here is some more food for thought to interested and optimistic people. The nitty gritty will be getting every compiler vendor onto the same boat, to make them throw away their bad implementations in favor of more generic code-graph evaluators.
  • C++20 modules are a great opportunity for constexpr-deduction!
  • the compiler vendor standpoint is wrong that their inlining optimizations beat constexpr-deduction; the increased control over evaluation by the program developer will increase optimization even further!
  • the always-constexpr-guy as the most negative example of C++ developer - expectation to evaluate everything at compile-time, coincidence with the skript kiddy, stark difference between full-possibility-value-set of dynamic user input against strictly-compiletime-evaluated interim-results, where the realization is key to become a great software developer thus introduction of constexpr-deduction improves the development debate
  • it should still be taught that not every function can be constexpr, but people can expect better code-gen if they find ways to define constexpr functions using the already existing C++ framework
Quiret (talk) 07:15, 9 January 2023 (PST)