assert has a single purpose - perform check in debug mode and terminate if it fails. Such checks are usually used to validate preconditions which can break function execution or are too expensive to perform them in release mode.
In your example you are trying to use assert to check precondition but it's actually not a precondition because your function can continue execution and do something valid (return 0 in your case). To fix your design either make it a real precondition:
int f(int* p){
assert(p);
return *p;
}

or make nullptr a valid input for your function:
int f(int* p){
if(!p){
return 0;
}
return *p;
}

What you propose is a weird mix of both, a thing which terminates in Debug but returns something in Release, this is not how good interfaces are made.

On Wed, Aug 17, 2022 at 5:52 PM Florian Gavril via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Hello,

As everyone knows that, the assert macro is very useful to find out unexpected conditions on the development stage, but for the production builds, the NDEBUG is usually enabled and assert is actually disabled. If assert is used, for example, in a function, to check if one of the parameters is not NULL, the program execution is terminated and some messages are displayed. But if NDEBUG is defined, the program will silently continue until the disaster happens. In order to avoid this situation, the programmer adds a double check for that parameter with a retur routine.

Basic example:
int func(int *p) {
  assert(p);
  if (p == NULL) {
    return 0;
  }
  ..........
  return 1;
}

My proposal is to re-define assert or define a new macro (let's say assertr, pretty much like assertm) which will take two arguments: condition and the return value for non-debug builds, In this case, the previous code may be compacted:
int func(int *p) {
  assertr(p, 0);
  ..........
  return 1;
}

Thank you,
Gabi Florian 

--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals


--
Regards,
Oleksandr Koval.