0

I have a class featuring a (public) function returning a vector (but it seems it's irrelevant).

std::vector<int> test() {
return std::vector<int>(1,0);
}

why am I allowed to call it just like a void function,

test();

without getting a compiling error, or at least a warning (Wall, pedantic)?

MarcDuQuesne
  • 305
  • 2
  • 10
  • 2
    Basically, similar to the reason you can do `x = 5` without using the return value from `operator=` – amit Jan 08 '13 at 13:40
  • @amit even more to the point: `5;` – WhozCraig Jan 08 '13 at 13:41
  • Related: [how to raise warning if return value is disregarded - gcc or static code check?](http://stackoverflow.com/questions/2042780/how-to-raise-warning-if-return-value-is-disregarded-gcc-or-static-code-check) – jrok Jan 08 '13 at 13:43
  • Once upon a time, the early C language didn't have a `void` type and functions defaulted to return an `int`. But you didn't have to save the return value if you didn't want it. And there we are. – Bo Persson Jan 08 '13 at 15:03

3 Answers3

6

You can discard the return value. It's no good style in general, but you can always do it.

That's one of the reasons why we can't overload on the return type. So if you'd define another function void test(), the call wouldn't be possible because of ambiguity.

If you want your compiler to warn such cases in which you (un)intentionally discard the return value, pass the flag -Wunused-result (for GCC). [I don't know the flags for other compilers]

In general, almost all return values make sense, so some people use this macro to detect cases where they unintentionally discarded the value, especially if the return value is something like an error code which should be checked afterwards.

If you want to enable the warning for a particular function, you can put an attribute at the end of the signature (also for GCC, for MSVC have a look at this question):

std::vector<int> __attribute__((warn_unused_result)) test() {
    return std::vector<int>(1,0);
}

See also: How to raise warning if return value is disregarded?

Thus, if you call the function but don't use the return value, you get a warning. Note that warnings don't make compilation fail, for this you need to add -Werror to the compiler flags.

Community
  • 1
  • 1
leemes
  • 44,967
  • 21
  • 135
  • 183
  • 1
    Might be worth mentioning `__attribute__((warn_unused_result))` – stefan Jan 08 '13 at 13:42
  • Re *It's no good style in general*. Sometimes it is good style. For example, both `std::cout << "Foo" << std::endl;` and `printf("%s\n", "Foo");` discard return values. Casting the return value from these calls to `void` (e.g., `(void)(std::cout << "Foo" << std::endl);` ) is pedantically correct nonsense. – David Hammen Jan 08 '13 at 14:23
  • @DavidHammen You're absolutely right. I was talking about stuff like `bool ok` as return values, which you *should* check on the caller side. But the compiler can't know... So, the best style would be to add attributes to such methods where the return value is really "to be checked". – leemes Jan 08 '13 at 14:50
0

Because the compiler simply discards the return value. There may be options to your compiler that warn about this, but it's not enabled by default.

leemes
  • 44,967
  • 21
  • 135
  • 183
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

It is an error to try to assign a void function return value to a variable (since there is no return value), but it is not an error to discard an actual return value. This is because the function call may still have a side effect, and perhaps the return value is only informative (e.g., a status code, when you're always expecting success). Because of scenarios like that, the language designers decided it is okay in C++ to call a non-void function without capturing the return value.

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134