close
The Wayback Machine - https://web.archive.org/web/20220512214553/https://en.cppreference.com/w/Talk:cpp/language/constexpr
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)