Omit Return Type in C++11

Omit return type in C++11

It would appear that g++ 4.8 is getting an implementation of auto return type deduction.
The patch was put in by Jason Merrill who is also sending a paper for C++-1Y for the feature. The feature is available with -std=c++1y.

Still playing with it.

Can you omit the return type in main function?

Never omit main's return type, as it's non-standard!


wandbox example:

prog.cc:1:6: warning: ISO C++ forbids declaration of 'main' with no type [-Wpedantic]
main()


From $3.6.1:

1 A program shall contain a global function called main, which is the designated start of the program. It
is implementation-defined whether a program in a freestanding environment is required to define a main
function. [ Note: In a freestanding environment, start-up and termination is implementation-defined; startup
contains the execution of constructors for objects of namespace scope with static storage duration;
termination contains the execution of destructors for objects with static storage duration. — end note ]
§ 3.6.1 58

2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall
have a return type of type int
, but otherwise its type is implementation-defined

Omit return type in function prototype

Could you please explain when can be omitted the return_type? Is this a mistake?

The return type may not be omitted in a regular function prototype. The resource you cited is very wrong to suggest otherwise. There is no rule in standard C++ that assumes a return type of int in a function prototype.

Or is some older version of C++?

Not of C++. C++ never allowed omitting the return type. But pre-standardized C (K&R C) did allow it and had an "implicit int" rule. And so some compilers offer an extension for compatibility with some really old C code.

But again, this isn't, nor ever was, standard C++.

When can we omit the return type in a C++11 lambda?

Your code is being accepted without any warnings because the original C++11 restriction is considered a defect in the standard, which allows implementations to fix the behavior. See CWG DR975, DR1048 and N3638.

975. Restrictions on return type deduction for lambdas

[Moved to DR status at the April, 2013 meeting as part of paper N3638.]

There does not appear to be any technical difficulty that would require the current restriction that the return type of a lambda can be deduced only if the body of the lambda consists of a single return statement. In particular, multiple return statements could be permitted if they all return the same type.

1048. auto deduction and lambda return type deduction.

...

Notes from the November, 2014 meeting:

CWG agreed that the change embodied in paper N3638 should be considered to have been a DR against C++11.

In summary, DR975 proposed modifying the rules for return type deduction for lambda expressions to allow multiple return statements.

DR1048 identifies a discrepancy where the rules for deducing the return type for normal functions using the placeholder type auto differs slightly from the rules proposed in DR975. Specifically, return type deduction for normal functions would discard top-level cv-qualifiers in all cases, where as those for lambda expressions would preserve cv-qualifiers for class types.

N3638 resolves this issue, amongst others.


I doubt there's any way to revert to the original behavior short of finding a compiler version that shipped with C++11 lambda support prior to the implementation of the DR above.

What if I omit the return type of main function in C?

C89/90 still has the implicit int rule, so main() is equivalent to int main(). By leaving off the return type, you've implicitly defined the return type as int. Some may consider this sloppy, but it's strictly conforming (i.e., involves no implementation defined, undefined or unspecified behavior).

For C99, the implicit int rule has been removed, so main() isn't defined. However, a compiler is only required to "issue a diagnostic" upon encountering a violation of a Shall or Shall not clause -- it's still free to continue compiling after issuing the diagnostic. Exactly what constitutes a diagnostic is implementation defined. As such, all that's needed for gcc to conform in this respect is documentation to say that the warning it issues is to be considered a diagnostic.

Edit: "implicit int" in the C89/90 standard isn't really a single rule in a single place -- it's spread around in a couple of places. The primary one is §6.5.2.1, where it says:

-- int, signed, signed int, or no type specifiers

This is part of a list, where all the items on each line of the list are considered equivalent, so this is saying that (unless otherwise prohibited) lack of a type specifier is equivalent to specifying (signed) int.

For function parameters, there's a separate specification (at §6.7.1) that: "Any parameter that is not declared has type int."

Omitting return statement in C++

Omitting the return statement in a non-void function [Except main()] and using the returned value in your code invokes Undefined Behaviour.

ISO C++-98[Section 6.6.3/2]

A return statement with an expression can be used
only in functions returning a value; the value of the expression is
returned to the caller of the function. If required, the expression
is implicitly converted to the return type of the function in which it
appears. A return statement can involve the construction and copy of
a temporary object (class.temporary). Flowing off the end of a
function is equivalent to a return with no value; this results in
undefined behavior in a value-returning function
.

For example

int func()
{
int a=10;
//do something with 'a'
//oops no return statement
}

int main()
{
int p=func();
//using p is dangerous now
//return statement is optional here
}

Generally g++ gives a warning: control reaches end of non-void function. Try compiling with -Wall option.

Is the usage of main without a return type phased out in C++11?

See also What should main() return in C and C++?

ISO/IEC 14882:1998 contains:

§7 Declarations

¶7 Only in function declarations for constructors, destructors, and type conversions can the decl-specifier-seq
be omitted.78)

and footnote 78 says:

The “implicit int” rule of C is no longer supported.

The same statements are in ¶9 and footnote 89 in the C++11 standard.

So, main() declared without the return type has never been a part of standard C++, but it was allowed roughly up until C++98 standard was created (and probably a bit longer for reasons of backwards compatibility).

If you look in Stroustrup's "Design and Evolution of C++" (published 1994), §2.8 The C Declaration Syntax says:

Allowing the type specifier to be omitted (meaning int by default) also led to complications. … The negative reaction to changes in this area from users was very strong. … I backed out the change. I don't think I had a choice. Allowing that implicit int is the source of many of the annoying problems with the C++ grammar today. … Finally, ten years later, the C++ ANSI/ISO standard committee has decided to deprecate implicit int. That means we may get rid of it in another decade or so.

Is the default return type in C++11 long?

There is no default return type in standard C++.

The IDE / compiler might be reusing the the same code that it is using for analyzing C89 definitions. I have no idea why is it long.

C++11 auto return type in template methods

A template argument cannot be deduced from the return type of a function template. Only parameters of the function template participate in template argument deduction. Since TInstance does not figure in any of the parameters of FindInContainer, it cannot be deduced.

If VS 2015 Update 1 supports it, you could use return type deduction (a C++14 feature) for the function template (omit the return type altogether):

template<typename THandle, typename TContainer>
auto FindInContainer(TContainer& container, THandle handle)
{
// ... as before
}

If that's not supported, you can resort to extracting the type from the container (as you're already doing):

template<typename THandle, typename TContainer>
typename TContainer::value_type FindInContainer(/*...*/)
{
// ... as before
}

Omit void as function result in C++

So, is there absolutely no way to omit void at the beginning of the function like with the function arguments?

No, there absolutely isn't. There is no function declaration syntax that doesn't have the return type in C++ nor in C99 or later. There used in C prior to C99, but the default return type would have been int rather than void.

Note that declarations void f() and void f(void) are not equivalent in C. Former declares a function with unspecified parameters while the latter declares a function with empty parameter list. In C++, both declare a function with empty parameter list.



Related Topics



Leave a reply



Submit