4

Consider:

void f() {
    return 5;
}

The above will raise errors. But why not this?:

template <typename = void> void f() {
    return 0;
}

I'm compiling with gcc-4.5.1. Why does it make a difference using templates such that I wouldn't receive errors from doing the same illegal return statement as a non-template function?. The only setback I get is that I can't call the function (i.e f()) without getting:

error: return-statement with a value, in function returning 'void'

But still, what could be the reason that I am able to define a return statement for a void function template?

Here is the code I have:

template <typename = void> void f() {
    return 0;
}

// pass

int main() {



}

The above code will pass despite a presumably illegal return statement in a function returning void.

3
  • You'll get +1 if you provide an actual testcase. We're having to guess at what you are and are not doing with the template f(). Commented Nov 6, 2012 at 17:08
  • @LightnessRacesinOrbit I updated. Commented Nov 6, 2012 at 17:14
  • That's the code where you get the error as expected. How about when you don't, as not expected i.e. the focus of the question? Commented Nov 6, 2012 at 17:28

3 Answers 3

10

Most of the checks are only done when you instantiate the template.

This is usually a good thing, as a code could work fine with one kind of template argument but fail to compile with another one. If you have template overloading, the compiler will even ignore candidates that fail to compile, see SFINAE.

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

6 Comments

@Kos What does template void f() do?
@David: Causes instantiation in a way that's not entirely clear to the first-time reader!
Instantiates the template, exactly that :)
This answer is a bit misleading: the program is ill-formed even if the template is never instantiated. The fact that most compilers use the no diagnostic required annotation in the standard and ignore the issue is a completely different issue. In particular, there is no value in ignoring this error until the template is instantiated: once the definition is seen the compiler can bail out and avoid the extra cost of processing.
@DavidRodríguez-dribeas when is the program ill-formed? Something like "If for arbitrary template parameters it's impossible to instantiate a template, then the program is ill-formed"?
|
7

You do:

template <typename = void> void f() {
    return 0;
}

int main()
{
    f<int>();
}

prog.cpp: In function 'void f() [with = int]':
prog.cpp:7:12: instantiated from here
prog.cpp:2:12: error: return-statement with a value, in function returning 'void'

Though the program is still ill-formed, the compiler is choosing not to diagnose the semantic error (which is its prerogative) because you're never actually instantiating that function.

3 Comments

Whether the template is used or not does not matter, the program is ill-formed even with no instantiation but the compiler is not required to diagnose it.
@DavidRodríguez-dribeas: I'm not sure about that.
@LightnessRacesinOrbit: I have posted the quote from the standard 14.6/8 in an answer.
6

This is a quality of implementation issue. The particular quote from the standard would be:

14.6/8 [...] If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. [...]

That is, your program is ill formed because that template cannot be used to generate any valid specialization, but the compiler is not required to diagnose this. When at a later time you instantiate the template, the compiler must generate the specialization, that specialization is not valid and the compiler complains.

You don't get an error in the template definition because the compiler is following the no diagnostic required path, i.e. ignoring the problem until it can no longer ignore it in the instantiation.

11 Comments

I would have interpreted the quote to mean that if the template isn't valid for any possible type then the template is ill-formed, not that a single invalid type makes it ill-formed.
@MarkB: I interpret the quote exactly as that: if the template isn't valid for any possible type then the template is ill-formed. That is the case in the question: template <typename T> void f() { return 0; } --> Regardless of the type T the function returns void and there is a return 0;
Let me get this straight. Does this mean that a compiler can generate an error even if I don't instantiate the template?
@KarolyHorvath: Yes, it means that the program is incorrect and a compiler can reject the program. It is allowed not to diagnose the problem, but the code is incorrect.
So I have two compilers, both standard comforming, and one compiles it while the other can reject it? The ***** of the c++ standard always amazes me.
|

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.