Why are function declaration mandatory in C++ and not in C? - c++

So one of my previous exams had this question, and till now I've been reading that you don't need a declaration in any of the languages?
Which is right? Will C++ give an error if there's no declaration, or will it run?

In a discussion that involves both C and C++ "function declaration" is a rather vague term. These languages are significantly different in this regard.
In C++ language there's only one kind of function declaration: declaration with all parameter types and return type. Such declarations are necessary because C++ language supports function overloading. In order to choose which function to call the compiler needs to know everything about the function and needs to know which overloaded versions of the function are available. If you "forget" to declare some overloaded version, it will not be considered by overload resolution. That is at least one of the reasons function declarations are necessary in C++.
In C language there are two kinds of function declarations: non-prototype declarations and prototype declarations (or simply prototypes). A prototype in C is pretty similar to C++ declaration - it includes all parameter types. Prototypes have always been required in standard C for variadic functions (functions with ... parameters). For non-variadic functions prototype declarations are not required even today. But starting from C99 at least non-prototype declarations are required for all other functions. In older C89/90 version of the language function declarations for non-variadic functions were not required.
So, that should basically answer your question. In C++ function declarations are required because language features rely on them critically. In modern C function declarations are also required just to make the code safer. In older versions of C function declarations were not required mostly simply because the language was defined to work without them.

Function declarations in C are not mandatory for legacy / backwards compatability reasons - if they were made mandatory then some old / legacy code somewhere would stop compiling.
I'd guess that they are mandatory in C++ becasuse C++ isn't a strict superset of C and so can make the sensible choice of making them mandatory.
You should always declare them however - see this question Must declare function prototype in C?
FYI in C99 function declarations are now mandatory.

Function declarations are mandatory in C. Prototypes, however, are optional, except in the cases of variadic functions and functions whose argument types would be altered by default promotions.

I can't answer for C.
In C++, for functions:
void foo(); is a declaration.
void foo() { .. } is a definition and a declaration.
You need at least one declaration in scope before you call foo().
Much the same is true for data variables.

Related

Are function prototypes necessary for C++?

Basically, I am reading through this book right here and in Section 1.6: Some Differences between C and C++ it is stated:
Another subtle difference between C and C++ is that in a C++ program,
all functions must be prototyped.
I am sure that this is not true from all the C++ programs that I have written. Is this only true for some versions of C++? Is it also true for C?
It has been true of C++ since the beginning (although in C++ it's just called a "declaration", not a "prototype").
As C existed decades ago, it allowed you to call a function without declaring it. You could, however, declare a function if you wanted to--usually to tell the compiler that it had a return type different from what the compiler would deduce on its own. So, in C a function declaration looks something like this:
long f();
Note that empty parens there. That's what separates a function "declaration" from a function "prototype" (though a prototype is basically a superset of a declaration, so a prototype also declares the function in question). A prototype always has something inside the parens to indicate the number and type of parameters the function accepts, on this general order:
short g(int a, double b);
If it doesn't accept any parameters, you have to put in void to indicate that:
int h(void);
If you leave the parens empty, that (as noted above) means it's a function declaration instead of a prototype--and that means you're telling the compiler the function's return type, but you're not telling it anything about the number or type of parameters.
C++ (since before it was called C++, if I recall correctly) has only had one concept instead of the two in C. In C++ every function must be declared--and a declaration always includes the number of parameters, and the type of each. This is absolutely necessary to support (for one obvious example) function overloading, where the correct function to call is determined from the number and types of arguments you pass in the call.
A function definition in C++ also acts as a function declaration. Every function must be declared, but the declaration doesn't have to be separate from the definition.
In reasonably modern C, you normally get pretty much the same--that is, a "new" (i.e., not ancient) type function definition also acts as a prototype for that function. As C was originally defined, it included a syntax for a function definition that looked like this:
int f(a, b, c)
int a;
short b;
long c;
{
// function body here
}
This defines the function, but the compiler treats it only as a function declaration, not a prototype--that is, it tells the compiler the return type, but the number and types of parameters (even though they're specified) are not used by the compiler in the same way they would be with a function prototype. C++ has never used or supported this style of function definition though.

Why is it necessary to include the return type in a function definition even if it's specified in the declaration?

When you define a function in a separate cpp file, why is the return type necessary to indicate which specific function you would like to define if the compiler knows that a method cannot overload another method with the same signature who only differ by return type? Isn't foo::bar(params) enough to specify this?
Header file
class foo{
public:
void bar();
};
Source file
foo::bar() //equivalent to function declaration? throws error
{...}
Thank you
I don't think there's any inherent reason that this couldn't be done, but using it would lead to inconsistency. After all, you don't have to declare a function if its definition is visible, but in that case, you'd have to include the return type. So function definitions that have a preceding declaration wouldn't need a return type, but function definitions that didn't, would. And if you removed the declaration you'd have to rewrite the definition. Altogether too much fiddling around.
EDIT: not to mention the convenience of having the return type in front of you when you're looking at the definition of the function.
It doesn't seem to be a design goal of C++ to eliminate all possible redundancy from programs.
That is not even a good goal to have, at least if taken to extremes.
It is useful for the same information to be repeated in two places, and have an error be flagged if they conflict.
Some programming languages have redundancy built into basic control syntax, like while condition ; do .. if condition ; then .... end if; ... end while; The while must be terminated by end while, and if by end if. The compiler then knows exactly which one is missing. Proponents of such languages insist that this is better than a diagnostic about one of fifteen possible braces not being closed. :)
The return type being repeated in the definition is also helpful to the programmer in another way: the programmer doesn't have to jump to the declaration to see what the return type is.
It would actually take extra work to remove the return type in some cases. Declarations in headers can be produced by exact copy and paste. Or even with automated tools. You wouldn't want a header-generating tool to strip away the return type from your definitions.
We should question the necessity of declarations in the first place. The definition of a function is the primary artifact; the declaration is something that is just factored out for the sake of a particular compilation model. In other words, the question is "given that we have a function definition, why do we have to repeat any part of it anywhere".
It's as simple as this. If you don't define a return type you are not defining a function. By definition a function declaration must have a return type. Think of forward declared functions. You always define a return type in both the forward declaration and the definition. Why? Because if you didn't it wouldn't fit the syntax of a function.
I suppose it wouldn't be necessary, logically speaking.
But C++ inherited its declarator syntax from C, in which a definition is also a declaration. A declaration requires a return type.
And, despite the obvious incompatibilities (member functions, for one), there was no reason to deliberately deviate from this.
If one were to write a brand new language, you could probably make it so that return types on definitions were optional, as long as definitions were not also declarations. Pre-definition declarations would become obligatory — a little cumbersome, if you ask me!

Why are there a handful of passing mentions of "function prototypes" in C++11? Surely these don't exist in C++

The C++11 standard makes a couple of passing mentions to "function prototypes".
There are not in any definitions of the relevant features, but in random places like:
"function prototype scope" in [C++11: 3.3.4] (whose definition actually admits it's talking about "function declarations");
an editorial description of the library type definition clauses in [C++11: 17.5.1.4/1], footnote 175 (which seems to be referring to the C functionality);
[C++11: 20.9.4.3/6] which describes the hypothetical template <T> typename add_rvalue_reference<T>::type create(); as "a function prototype".
the same thing at [C++11: 20.9.6/4];
appendix [C++11: C.1.7] which talks about declarators in C: "The function declarations using C incomplete declaration style must be completed to become full prototype declarations, then later "Rationale: Prototypes are essential to type safety".
... and that's it.
Surely, we are set on the "declaration"/"definition" terminology and, since the C++ standard does not use the "prototype" terminology in its core definitions, these are merely typos/inconsistencies, introduced because some editors are familiar with C terminology?
Or is there some subtle meaning I'm missing?
Yes and no. I think some of the uses of "prototype" make sense, but others should really be changed to "declaration".
I agree that §3.3.4/1 should talk about "function declaration scope" instead of "function prototype scope".
§17.5.1.4 is talking about C++ headers, so I think it should probably use "declaration" instead of prototype.
Footnote 175 is specifically referring to what is provided by C headers, so there I think it's probably appropriate to use C terminology (i.e., to continue to use "prototype", though possibly with an added note that this is equivalent to a C++ declaration).
I'd agree that the use of "prototype" at §20.9.6/4 and §20.9.4.3/6 are both mistakes, and should use "declaration" instead.
C.1.7 is specifically comparing C to C++, talking about declarations vs. prototypes in C and how they compare to C++ declarations, so it nearly needs to retain the use of "prototype" to be meaningful.
As to a definition of "prototype" (or related features), ISO 9899:1999 (through TC 3) is a normative reference to the C++ standard, so its definition of "prototype" can be applied since the C++ standard itself provides none.

Why add void to method parameter list

I've seen methods with the following signature:
void foo (void);
They take no argument, however I'm wondering whether doing this is useful or not. Is there a reason why you would want to do it?
This is a holdover from older versions of C, where foo() meant "a function with an unknown number of parameters" and foo(void) means "a function with zero parameters." In C++, foo() and foo(void) both mean "a function with zero parameters", but some people prefer the second form because it is more explicit.
The C++03 standard says (emphasis mine):
8.3.5.2
The parameter-declaration-clause determines the arguments that can be
specified, and their processing, when the function is called. [Note:
the parameter-declaration-clause is used to convert the arguments
specified on the function call; see 5.2.2. ] If the
parameter-declaration-clause is empty, the function takes no
arguments.
This means that if you are talking to the compiler it's just a matter of taste.
If you are writing code that will be read by others, then the C++ way of doing things is
void foo();
The other form remains valid only for reasons of compatibility with C, where there was a difference among the two signatures.
In C++ code there is no reason whatsoever to use void in this way. What's more it is very much not the idiomatic way to declare parameterless functions.
This is a legacy from the older versions of C for functions with no arguments.

C++ standard on export of Templates, can any one explain it?

A namespace-scope declaration or definition of a non-inline function template, a
non-inline member function template, a non-inline member function of a class
template or a static data member of a class template may be preceded by the export
keyword. If such a template is defined in the same translation unit in which it is
declared as exported, the definition is considered to be exported. The first
declaration of the template containing the export keyword must not follow the
definition.
What is actually meant in the above statement?
Please any one expalin with program?
This complex paragraph means that if you declare a templated class as exported before defining it, and then in the same translation unit (effectively, file after preprocessing) you actually define the class, the class definition is exported. But if you define the class and then have a prototype with the "export" keyword, it's not.
There, that's English, right?
The export keyword is meant to enable templates being declared in header files, but defined in implementation files - the way it is usually done with any other function.
Unfortunately, compiler manufacturers have more or less ignored the export keyword for the last decade. GCC maintainers and Microsoft will tell you there is not enough "demand" for that feature (how surprising - next-to-no-one supports it, so no-one knows about it, as your question aptly proves). They'll also tell you that it is too difficult to implement effectively.
(Background: That's what the EDG people said in the C++ committee meetings, but the others insisted on adding it to the standard. In the end, the EDG people were the first and, sadly, the only ones to this day who actually implemented this feature in their compiler frontend, as far as I know.)
So, for all practical purposes, you can ignore the above statement. Templates have to be defined in header files, and cannot be "declared" at all, because all compiler frontends except the EDG one are not standard compliant in this regard.