I have a function which returns a pointer. In this function I want to check a condition. If this condition is satisfied, I want to return the pointer. However, if the condition is not satisfied I want to print an error log and do not return anything. What should I do in this case? I am not returning anything if the condition is not satisfied but I am getting a warning. Thanks
-
1In a non-void function you have to return _something_. Usually a `nullptr` signals an error. – Lukas-T Oct 24 '20 at 19:14
-
For the record: a program where execution reaches the closing brace of a non-`void` function without encountering a `return` statement exhibits undefined behavior. – Igor Tandetnik Oct 24 '20 at 19:15
-
1Another way is to throw an exception, if you can't return anything reasonably. – πάντα ῥεῖ Oct 24 '20 at 19:15
-
What do you expect the calling function to do in that case? How would it know if you've returned a pointer or not? – 1201ProgramAlarm Oct 24 '20 at 19:16
-
2C or C++? Choose one – klutt Oct 24 '20 at 19:16
-
2You *could* return an `optional` pointer, but you'd still be returning *something*. Besides, `nullptr` already contains the same information. – cigien Oct 24 '20 at 19:16
-
@1201ProgramAlarm I want it to be ignored. Just print an error log, which indicates requested pointer is invalid. – efe373 Oct 24 '20 at 19:18
-
@klutt if you give an answer to one, I can find the relevant answer in the another. However, C++ is preferred – efe373 Oct 24 '20 at 19:19
-
2@EfeBerkay _"I can find the relevant answer in the another."_ I seriously doubt that, c and c++ are very different languages. – πάντα ῥεῖ Oct 24 '20 at 19:21
-
4How do you find a C answer if we tell you "throw an exception"? – StoryTeller - Unslander Monica Oct 24 '20 at 19:22
-
@StoryTeller-UnslanderMonica I thought I can, thanks for correction to both you, klutt and πάντα ῥεῖ. Appreciated – efe373 Oct 24 '20 at 19:24
-
`Foo* get_foo(bool condition) { if (condition) return pFoo; std::exit(EXIT_FAILURE); }` assuming there is a `pFoo` somewhere. – Eljay Oct 24 '20 at 19:27
-
Let's call your function `foo()`. Let's say you have this declaration: `int *ptr = foo();` What value should `ptr` have on failure? It cannot have none. – klutt Oct 24 '20 at 19:35
-
Exceptions are pretty much the holy grail here, but if for some reason you really can't (or write C as you kind of talked about), what you can do is to change a signature like `T my_function()` to `int my_function(T& target)`, which the actual return value being the parameter as a reference (called "pass by reference") and the integer that the function directly returns being an error code, zero if no error occured. That is pretty much the reason why it is `int main()` and not `void main()`. But again, that would be C style, in C++, simply throw an exception. – Aziuth Oct 25 '20 at 09:05
-
(Note: another possibility would be `int my_function(T* target)`, but I advise against that. Pointers can be null pointers, and also this way it is not clear when `target` is initialized - a reference can be assumed to already be, at least if you have the standard of never leaving any variable uninitialized.) – Aziuth Oct 25 '20 at 09:08
2 Answers
However, if the condition is not satisfied I want to print an error log and do not return anything.
Well, unless you want to exit the program or throw an exception or something like that, this is not really possible. And the most common way to solve it when you have a function that returns a pointer is to return a null pointer.
One very bad way of "solving" it is simply skipping the return statement, like this:
int *foo() {
if(<condition>)
return <some pointer>
log(<message>);
// Simply skip the return statement here
}
I would STRONGLY advice against it, because it's undefined behavior. And since it only needs one line to avoid that, just add a return nullptr
in the end. Please note that since reaching the final }
is UB, the compiler might optimize the above function to:
int *foo() {
return <some pointer>
}
Yep, it skipped both the log message and the condition. The reason is that the compiler may assume that UB never happens.
Also, "returning nothing" does not really make sense. Consider this code:
int *foo() {
// Code
}
int main() {
int *ptr;
ptr = foo();
printf("%p\n", ptr); // What should the output here be?
It does not make much sense to "return nothing" because ptr
has to be assigned SOME value. There are only two reasonable solutions that I can think of:
ptr
does not get modifiedptr
gets a "none" value
1 is not possible, because C++ simply does not support that. A workaround is something like this, but it requires passing the pointer to the function:
int *foo(int *ptr) {
if(<condition>)
return <some pointer>
return ptr;
}
2 is not possible. C++ does not have a "none" value. The closest you can get to that is simply a null pointer. For floating point numbers, you can instead use the NaN number. But there's no universal "none" that works for all types.

- 30,332
- 17
- 55
- 95
-
this might cause some bugs if the statement is not adressed so you need to add another ```return
``` at the end of the function even if that's just gonna be ```return nullptr``` not returning something in a non-void function is not always a good idea~ – Astro Oct 24 '20 at 20:10 -
1If you simply skip the return statement, instead trying to log an error, the compiler can say, "Oh, this log statement can never execute, because if it did, we'd hit undefined behavior. Let me remove that log statement for you" – Justin Oct 24 '20 at 20:22
-
1@gamercodeman and Justin : Isn't it clear enough as it is? I mean, I say it's "very bad" and I mention that it's UB. – klutt Oct 24 '20 at 20:34
You can use std::optional
since C++17. Example:
#include <iostream>
#include <optional>
std::optional<int> test(int a){
if (a > 10){
return std::optional<int>{a} ;
}
else{
std::cout << "Error!";
return {};
}
}
int main(){
std::cout << test(9).value_or(0) << std::endl;
return 0;
}

- 3,173
- 1
- 14
- 26