1

I am trying to compile the following C++ code (saved as example4.cpp)

#include <iostream>

using namespace std;

constexpr double nth(double x, int n);//initialization

int main()
{
double x=2;
int n=5;
nth(x,n);//Function call
return 0;
}


constexpr double nth(double x, int n)   // function definition
{
    double res = 1;
    int i = 0;
    while (i<n) {   // while-loop: do while the condition is true
         res*=x;
         ++i;
    }
cout << res;
cout << endl;
    return res;
}

This code is giving the following error:

> example4.cpp: In function ‘constexpr double nth(double, int)’:
> example4.cpp:24:9: error: call to non-constexpr function ‘std::basic_ostream<_CharT, _Traits>::__ostream_type&
> std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT =
> char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT,
> _Traits>::__ostream_type = std::basic_ostream<char>]’
> cout << res;

Can anyone please suggest?

Thank you.

3
  • 9
    Think of how hard it is to write to the user's console at compile time. Commented Mar 25, 2020 at 0:03
  • Consider removing the debug statements from the function and changing nth(x,n); to cout << nth(x, n) << endl; Commented Mar 25, 2020 at 0:10
  • It worked! Thank you Commented Mar 25, 2020 at 1:01

1 Answer 1

7

Streaming to std::cout is not allowed in a constexpr function context. In fact, only a limited set of things are. Read the cppreference article on constexpr.

Sign up to request clarification or add additional context in comments.

6 Comments

std::cout << is allowed in a constexpr function and almost everything is, but there is another rule that requires a constant expression calling the constexpr function to exist in principle. A constant expression cannot execute a call to std::cout <<, but nth will always call std::cout <<, so it can never be used in a constant expression. See also en.cppreference.com/w/cpp/language/constant_expression.
For example, if OP adds if(n<0) return 0; at the top of the function body, then the program will have well-defined behavior and work as expected.
The insertion operators not marked constexpr, so doesn't that mean a call to those operators aren't allowed anywhere in a constexpr function body?
No, it does not mean that. If you look at the requirements you linked, you will see that there is no such requirement. The only requirement that OP is violating is "there exists at least one set of argument values such that an invocation of the function could be an evaluated subexpression of a core constant expression" and this causes undefined behavior, so it is not required to be diagnosed by the compiler. Adding any execution path that would avoid the std::cout << evaluation for some set of arguments (whether actually used or not) would make the program well-behaved.
So does that mean there just has to be at least one code path that does not contain any calls to non-constexpr functions, so long as only constexpr code paths are taken in constexpr contexts?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.