Author Topic: C++ "constexpr" function arguments  (Read 3407 times)

0 Members and 1 Guest are viewing this topic.

Offline westfwTopic starter

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
C++ "constexpr" function arguments
« on: September 26, 2019, 09:55:57 am »
So, C++ has constexpr "variables" and "functions."
Does it have an equivalent for function ARGUMENTS?
Ideally, I'd like to have overloaded functions:void foo(constexpr int bar) { ... }

void foo(int bar) { ... }
so that if I call foo() with a compile-time constant as an argument, it would invoke the first code, and if it wasn't, it would invoke the second...
(Yeah, I'm aware that I can do about the same thing using __builtin_constant_p(), at least with gcc.  But that tends to be ugly, and not portable, and it seems like the sort of thing  that would get standardized, eventually.)
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3032
  • Country: us
Re: C++ "constexpr" function arguments
« Reply #1 on: September 26, 2019, 01:11:27 pm »
Doesn't seem possible at the moment, but there is a proposal in the works:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1045r0.html


Here's a discussion on implementing is_constexpr() function for C++2a:

https://stackoverflow.com/questions/55288555/c-check-if-statement-can-be-evaluated-constexpr


Here's an old SO discussion of the problem:

https://stackoverflow.com/questions/8936549/constexpr-overloading

At that time looks like the best way to discriminate based on a constexpr parameter was to write a macro which called one implementation or another based on the return value of __builtin_constant_p().

 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14300
  • Country: fr
Re: C++ "constexpr" function arguments
« Reply #2 on: September 26, 2019, 03:09:27 pm »
Just a thought or question about that...

As I get it, constexpr represents expressions that can be fully evaluated statically (at compile-time).
I guess obviously any litteral, or a combination thereof, is a constexpr. But there are possibly many other, more subtle cases, in which some expression can actually be fully evaluated statically, whereas it's really NOT obvious to the eye of the programmer. In that case, isn't using constexpr potentially very slippery, especially if you're making assumptions on what a constexpr is, and implements functions that act differently for constexpr parameters (something not currently available, and I guess, what I just said was probably part of the discussions?)

Overloaded functions can be so slippery already.
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3032
  • Country: us
Re: C++ "constexpr" function arguments
« Reply #3 on: September 26, 2019, 04:00:12 pm »
The consensus seems to be that constexpr evaluation is Turing-complete:

https://github.com/llvm-mirror/clang/blob/master/test/SemaCXX/constexpr-turing.cpp

In C++11 it wasn't, but apparently it has since been fixed:

https://stackoverflow.com/questions/9201506/is-constexpr-based-computation-turing-complete/9528554#9528554

Template meta-programming is also Turing-complete so now there are two ways to hang your compiler.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14300
  • Country: fr
Re: C++ "constexpr" function arguments
« Reply #4 on: September 26, 2019, 07:18:44 pm »
(...)
Template meta-programming is also Turing-complete so now there are two ways to hang your compiler.

Good lord. :-DD

Someday someone will write a full graphics Tetris game intended to run at compile-time inside a C++ compiler.
 ;D
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6733
  • Country: pl
Re: C++ "constexpr" function arguments
« Reply #5 on: September 26, 2019, 08:01:37 pm »
As I get it, constexpr represents expressions that can be fully evaluated statically (at compile-time).
I guess obviously any litteral, or a combination thereof, is a constexpr. But there are possibly many other, more subtle cases, in which some expression can actually be fully evaluated statically, whereas it's really NOT obvious to the eye of the programmer. In that case, isn't using constexpr potentially very slippery, especially if you're making assumptions on what a constexpr is, and implements functions that act differently for constexpr parameters (something not currently available, and I guess, what I just said was probably part of the discussions?)

Overloaded functions can be so slippery already.
There are constexpr variables and functions, and those are recognized by being marked as such. There are some criteria as to which functions are allowed to be constexpr, which guarantee that the function can actually be computed at compile time. Or so they did in C++11, anyway ;)
Not sure if such a thing as "a constexpr expression" is defined, but we could agree that any expression which doesn't refer to non-constexpr variables or functions "is constexpr". Then the concept is quite well defined, because constexpr variables and functions are well defined.

By the way, template instantiation cannot actually hang most compilers. They impose some limits (like 1000) on the depth of template instantiations.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14300
  • Country: fr
Re: C++ "constexpr" function arguments
« Reply #6 on: September 29, 2019, 04:01:22 pm »
There are constexpr variables and functions, and those are recognized by being marked as such. There are some criteria as to which functions are allowed to be constexpr, which guarantee that the function can actually be computed at compile time. Or so they did in C++11, anyway ;)
Not sure if such a thing as "a constexpr expression" is defined, but we could agree that any expression which doesn't refer to non-constexpr variables or functions "is constexpr". Then the concept is quite well defined, because constexpr variables and functions are well defined.

My point was not that constexpr was not well defined. My point was explicitely about using constexpr in function parameters to write different overloaded methods (which apparently is not yet allowed, and that's why I think it makes sense that it's not), which is what the OP was willing to do.

Compilers will know what expressions can be compatible with constexpr (can be fully evaluated at compile-time), but my point was that it may NOT be as trivial for programmers, so that the programmer MAY not know which version of an overloaded function will be called in some particular situation. The OP's query was exactly where constexpr as parameters could become slippery to handle.

By the way, template instantiation cannot actually hang most compilers. They impose some limits (like 1000) on the depth of template instantiations.

There most likely is a limit, but is it documented? Can you point us to a reference for that for GCC for instance?
And then, as it's supposed to have become Turing-complete, can't there be some cases in which you could make definitions "loop" in some way without exceeding the max depth?
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6733
  • Country: pl
Re: C++ "constexpr" function arguments
« Reply #7 on: September 29, 2019, 06:05:36 pm »
Perhaps you are right, actually.

I looked up the details of what constitutes a "constant expression" at cppreference.com and while it starts reasonably (don't use non-const/uninitialized variables, don't call non-constexpr functions, don't pass non-constant arguments to functions, don't use anything declared but not defined, avoid UB) it quickly wanders into a hairy mess of rules about casting, inline assembly, implicit conversions,  ... :scared:

As for template depth in GCC, sure
Quote
-ftemplate-depth=n

    Set the maximum instantiation depth for template classes to n. A limit on the template instantiation depth is needed to detect endless recursions during template class instantiation. ANSI/ISO C++ conforming programs must not rely on a maximum depth greater than 17 (changed to 1024 in C++11). The default value is 900, as the compiler can run out of stack space before hitting 1024 in some situations.

Each template instantiation directly instantiates only some finite number of additional templates (as they occur in the definition) so to instantiate infinitely many templates you have to go infinitely deep. That being said, with fanout of 1000000 and 1000 levels depth there isn't much practical difference ;)
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14300
  • Country: fr
Re: C++ "constexpr" function arguments
« Reply #8 on: September 29, 2019, 06:19:36 pm »
1024 in C++11... that sounds already crazy. ;D

But as I said,  I additionally wonder whether there could be other ways of hanging the compilers than using recursive templates...
I'm not keen enough on all the possibilities for C++ metaprogramming...
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3032
  • Country: us
Re: C++ "constexpr" function arguments
« Reply #9 on: October 11, 2019, 06:52:52 pm »
This just showed up... it goes over proposed extensions to the use of constexpr in function parameters including overloading:

https://youtu.be/bIc5ZxFL198?t=6m15s

 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14300
  • Country: fr
Re: C++ "constexpr" function arguments
« Reply #10 on: October 17, 2019, 04:50:11 pm »
C++ makes me think more and more of some kind of "all you can eat" buffet...
 ::)
 

Offline paullo

  • Newbie
  • Posts: 9
  • Country: scotland
  • Another smoke machine in the post
Re: C++ "constexpr" function arguments
« Reply #11 on: November 04, 2019, 02:02:40 pm »
Someday someone will write a full graphics Tetris game intended to run at compile-time inside a C++ compiler.

Already been done :) https://blog.mattbierner.com/stupid-template-tricks-super-template-tetris/
 
The following users thanked this post: SiliconWizard

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14300
  • Country: fr
Re: C++ "constexpr" function arguments
« Reply #12 on: November 04, 2019, 02:22:17 pm »
Someday someone will write a full graphics Tetris game intended to run at compile-time inside a C++ compiler.

Already been done :) https://blog.mattbierner.com/stupid-template-tricks-super-template-tetris/

 :-DD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf