-1

Consider these two demonstrative programs (sizeof( unsigned long ) == sizeof( unsigned long long )).

The first one is

#include <iostream>

unsigned long f( unsigned long n )
    requires ( not( ( sizeof( unsigned long ) == sizeof( unsigned long long ) ) ) )
{
    return n;
}

int main()
{
    std::cout << f( 0 ) << '\n';
}

The compiler issues an error

error: cannot call function 'long unsigned int f(long unsigned int) requires !(sizeof (long unsigned int) == sizeof (long long unsigned int))'

But when a requires expression is used in the requires clause like this

#include <iostream>

unsigned long f( unsigned long n )
    requires requires { not ( sizeof( unsigned long ) == sizeof( unsigned long long ) ); }
{
    return n;
}

int main()
{
    std::cout << f( 0 ) << '\n';
}

The program compiles and run.

Is it a bug of the compiler or did I miss anything?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335

1 Answers1

4

This is normal. The following:

requires ( not( ( sizeof( unsigned long ) == sizeof( unsigned long long ) ) ) )

means that the function participates in overload resolution if the condition is true. In your case, the condition is false since, on your implementation, unsigned long and unsigned long long have the same size. Thus, the function is removed from overload resolution.

On the other hand, in the following:

requires requires { not ( sizeof( unsigned long ) == sizeof( unsigned long long ) ); }

the inner requires expression is the condition, and it is always true, since it is effectively just testing whether its operand is well-formed, which of course it is, regardless of whether it happens to be true or false. Since the condition is always true, the function participates in overload resolution.

Further reading: https://stackoverflow.com/a/54203135/481267

Brian Bi
  • 111,498
  • 10
  • 176
  • 312