Isn't a semicolon (';') needed after a function declaration in C++? - c++

I just recently took an intermediate programming test, and one of the questions I got wrong was as follows:
A semicolon (';') is not needed after a function declaration.
True or False.
I chose "false" (and please correct me if I'm wrong because I feel like I'm going crazy), a function declaration is what you write before the definition (at the top of the code) so the compiler knows the function call before even calling it, and a function definition is what makes up the function as a whole.
I.e.,
Declaration:
int func();
Definition:
int func() {
return 1;
}
Shouldn't the answer to this be false?

You can have a situation where you declare and define the function in one step, i.e. if you include the function definition at the point where you're declaring it. So technically I suppose true is correct. But the question is worded in such a way that I would have answered it the way you did.

In addition to the "a definition is also a declaration" thing, the following is legal C++:
int f(), g();
This declares two functions,f and g, both without arguments and with a return type of int, but the definition of f is not followed (immediately) by a semicolon. Likewise, this is legal:
int f(), i = 42;
But it is indeed not allowed to omit the semicolon entirely in these cases, so it would be somewhat surprising if either was taken as an example of a declaration without a following semicolon. In fact, the following is illegal:
void *p, f() {}
Other than a (mere) function declaration, a function definition cannot be combined with any other declaration or definition to the same type-specifier. (If this were legal, it would define both a void *p and a void f() {}.)
In any case, this seems to be a "gotcha" type of question that should not be in an intermediate programming test.
(Oh, by the way, please don't actually write code like int f(), i = 42;.)

The other answers and comments call out several of the many ways that this is a horrid, misleading and badly-written question. But there is another problem that no one else has identified yet. The question is:
A semicolon (';') is not needed after a function declaration. True or False.
OK, let's look at a function declaration:
int func(); /* */
/* ^ */
/* | */
/* That whitespace is "after the function declaration". */
That whole thing is the declaration. The declaration is not int func() and then followed by a ;. The declaration is int func(); and then is followed by whitespace.
So, the question is: is a semicolon needed after the declaration? Of course not. The declaration already has a semicolon in it which terminated it. A semicolon after the declaration would be pointless. By contrast, int func(); ; would be a semicolon after a function declaration.
The question was almost certainly intended to ask the question "true or false: the last token in a function declaration is always a semicolon" But that's not the question that they wrote, because the author of the quiz was not thinking clearly about the problem.
My advice is to avoid programming language quizzes altogether. They're pretty awful.
Fun fact, while we are on the subject. In C#, these are all legal:
class C {}
class D {};
struct E {}
struct F {};
In C#, a class or struct declaration may end in a semicolon, or not, at your discretion. This odd little feature was added for the benefit of C/C++ programmers coming to C# who have it in their fingertips that type declarations end in a pointless semicolon; the design team didn't want to punish them for having this habit. :-)

You can declare a function like this too:
int func(){
return 1;
}
The statement is very ambiguous. The right answer should be: it depends on how you declare the function.
Anyway, I'd have chosen false too, and maybe you can report the question to someone.

A semicolon (';') is not needed after a function declaration.
True or False.
True. A semicolon is not needed after any declaration. Nor after any definition. Nor after any statement.
Many kinds of declaration have to end with a semicolon, as the syntax in section 7 [dcl.dcl] specifies. But there is never any need to write a second one after that.

This depends on whether we are declaring or defining the function.
If we are declaring the the function, we need to include the semicolon (;), and if we are defining the function, the semicolon is not needed.
A declaration is like this:
int add(int, int);
And a definition is like this:
int add(int a, int b)
{
// ...
}

Even though I agree with almost all of the other answers, stating that the question is worded very ambiguous, and that your answer is technically correct, allow me to give a different perspective:
This is how I've always called them:
void func(); // The function prototype
...
void func()
{
// The function definition
}
I'm assuming the question was made up with this terminology in mind.
Definition and declaration are both the same concept in my eyes. "I define x = y" == "I declare x = y".
But of course, there's a big difference between the function prototype (on top) and the actual definition of the function.

It's a pity the question that you took doesn't say "directly after". We could for example write this:
int func() /* My function */ ;
Or I could write:
int func()
int a = 42;
In the first case the semicolon is not directly after the declaration, but that would be OK.
In the second case there is a semicolon "after" the declaration, but not directly after.
I think Eric Lippert has the right idea in his answer.
It's like saying "should there be a period after the end of a sentence in English?". Arguably, a sentence already has a period at the end (otherwise it wouldn't be a sentence) and therefore there should not be a period after the sentence..

You can use ; for prototypes only.

It's kind of a tricky question, but they used the word declaration which means something like this:
int example();
So it's true in this case.
If they'd used the word implementation then it'd been false.

Semicolon (;) is used to tell the compiler that after this semicolon (;) a new statement starts.
So I think the semicolon (;) is required during a function declaration only. So according to me, the answer will be true.

When functions are defined before main():
Don't need semicolon because the function is already defined
When functions are defined after main():
Need semicolon because because you are prototyping that function and telling the compiler that the function exits.

Related

Can I declare multiple functions with comma?

Can we use , operator to declare multiple functions once ?
This code compiles on gcc:
void f(), g();
void f() {}
void g() {}
int main() {
f();
}
Is it standard or a particularity of the compiler ?
It's standard. Look at all the things you can declare:
int a, *pa, f(int), *g(int);
This is a single declaration, with a single type specifier int and four declarators. Note that the two variable declarations there have different types, despite having the same type specifier. Same deal with the two function declarations. The type specifier only covers the innermost nugget of the type; the individual declarators wrap it in things like pointers or function-ness.
The function definition int f() { ... } is unique and unusual. While it serves to both declare and define a function, and involves some of the same syntactic constructs as declarations, it is syntactically separate from a declaration. Since a declaration is the thing that gets to have a list of declarators, the function definition syntax doesn't inherit that behavior. So you can declare multiple functions in a single declaration, but a function definition is not a declaration (despite the fact that it declares a function!) so you can only do one at a time.
Editorializing a little: This facet of the syntax, with type information spread between the type specifier and the declarator, is one of the core awfulnesses of C and C++. It dates back to the earliest days of C, when the focus of the language meant that most variables were ints and the type was actually the most optional part of a declaration. Most of us have experienced this in the form of int* a, b only making one pointer, but things like the parentheses that crop up when declaring function pointers, and the overall spiral-ness of complex type definitions, also spring from that essential, never-corrected mistake from the early 1970s.

Why custom type of function can only use for declaration? [duplicate]

From § 8.3.5.11 of ISO/IEC 14882:2011(E):
A typedef of function type may be used to declare a function but shall not be used to define a function
The standard goes on to give this example:
typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // ill-formed
void fv() { } // OK: definition of fv
What motivates this rule? It seems to limit the potential expressive usefulness of function typedefs.
Though this question is about C++, but since C++ inherits typedef and function pointer from C, so an explanation of the same question in C can be used in here. There's a formal explanation for C.
Rationale for International Standard - Programming Languages C §6.9.1 Function definitions
An argument list must be explicitly present in the declarator; it cannot be inherited from a typedef (see §6.7.5.3). That is to say, given the definition:
typedef int p(int q, int r);
the following fragment is invalid:
p funk // weird
{ return q + r ; }
Some current implementations rewrite the type of, for instance, a char parameter as if it were declared int, since the argument is known to be passed as an int in the absence of a prototype. The Standard requires, however, that the received argument be converted as if by assignment upon function entry. Type rewriting is thus no longer permissible.
It's probably mostly historical reasons. typedef was a relatively late addition to C, and was tacked onto the existing language (and caused a few problems for the parsing phase of compilers).
Also, a function definition has to define the names of the parameters, if any. A function type includes the function's return type and parameter types, but not its parameter names. For example, these:
void (int)
void (int x)
void (int y)
are three ways of writing the same function type. If you had:
typedef void func_t(int);
then this hypothetical definition:
func_t some_func { }
wouldn't define a name for its int parameter. I'm not sure how that could have been resolved in a reasonable manner. It would be possible, I suppose, but it was never done.
But the bottom line is probably just that Dennis Ritchie either didn't think it was worth the effort to define how a typedef could be used in a function definition, or he simply didn't think of it.
Let me put a few words. Consider a statement:
typedef void F(int p1, char* p2);
This statement assigns name F to a function signature void (int, char*); This is definition of an alias to the function signature. After that the statement:
F fv;
tells that there is a function fv. It has the signature that was mentioned above and it has its body somewhere. Look at the C/C++ syntax of the function definition:
retType funcName(params) { body }
There are actually 2 names used retType and funcName. None of them are the same to the name F from the initial typedef. The name F has meaning of both names. If language would allow something like:
F { body }
this will associate body with the function type. But this leads a problem:
The meaning of F would be not clear. Is it an "alias to the function signature" or is it a "name of the entry point into a code"?
Plus the syntax of the last example would be weird to millions of C/C++ programmers.
The rule is as you quoted - typedef of function type shall not be used to define a function. In the 3rd line of the example, you are trying to define a function with function type F. This is not allowed by the standard.
EDIT
As you pointed out, I try to explain more on it.
For the 3rd line, if it were legal, then you could replace F with the typedef definition:
void fv { }(). This is not a legal definition or declaration in C++.
I think the key point is that typedef is just creating an alias for simplification, and you can replace your typedef type like replacement of #define during compilation.

Difference between prototype declaration and forward declaration?

So I have this code:
class xx
{
int getnum(); //Is this a forward declaration or a prototype declaration and why?
};
int xx::getnum()
{
return 1+3;
}
So the question has already been commented in the code but:
Is int getnum(); a forward declaration or a prototype declaration and why?
Neither the term "forward declaration" nor "prototype declaration" are defined in the C++ standard, so very strictly speaking, it's neither. It is simply a declaration. If you want to be more specific, you could call it a non-defining declaration, or "a declaration which is not a definition."
When the words "forward declaration" are used in the standard, they are used to refer to declarations which declare, but do not define, the thing (function or class) they declare. Following this usage, int getnum() is therefore a forward declaration.
"Prototype declaration" of a function is used even less in the standard(1), and mostly when talking about [in]compatibility with C. However, when used, it refers to the exact same concept as a forward declaration of that function. Going by this, you could also call int getnum(); a prototype declaration.
To summarise, the terms "forward declaration" and "prototype declaration" have no formal definition, but from the way they are normally used and understood, int getnum(); can be described as either.
(1) However, a similar term "function prototype scope" is defined in the standard (C++17 N4659 [basic.scope.proto] 6.3.4/1). It establishes the scope of function parameter names in a non-defining function declaration, and it's the closest enclosing function declarator.
C++ only allows full prototype declarations of functions, unlike C in which something like int getnum(); could be a forward declaration of something like int getnum(int);
C.1.7 Clause 8: declarators [diff.decl]
8.3.5
Change: In C ++ , a function declared with an empty parameter list takes no arguments. In C, an empty
parameter list means that the number and type of the function arguments are unknown.
Example:
int f(); // means int f(void) in C ++, int f( unknown ) in C
Rationale: This is to avoid erroneous function calls (i.e., function calls with the wrong number or type of
arguments).
Effect on original feature: Change to semantics of well-defined feature. This feature was marked as
“obsolescent” in C.
Difficulty of converting: Syntactic transformation. The function declarations using C incomplete declaration style must be completed to become full prototype declarations. A program may need to be updated further if different calls to the same (non-prototype) function have different numbers of arguments or if the
type of corresponding arguments differed.
A forward declaration is a declaration of an identifier (denoting an entity such as a type, a variable, a constant, or a function) for which the programmer has not yet given a complete definition.
On the other hand a prototype refers to a function not an identifier.
Hope the following clear things out for you!
int getnum(); // Function prototype. You have not yet implemented the body of getnum() function, thus its a forward delcaration.
class RandomClass; // Forward declaration of RandomClass. You have not yet implemented this class but you need it for the rest of your code.
class xx{
RandomClass *foo; // Our need of having a member like that, made us make a forward declaration of the class RandomClass, above class xx
void BarFunction(); // Function Prototype!
};
int getnum(){ //This is the simply the body of your prototype above. Has nothing to do with the classes
return 1+3;
}
void BarFUnction(){
cout << "foo-bar\n" ;
}
Forward declaration is a type of declaration where you specify an Identifier for a Variable, Constant, Type or a Function without giving it's implementation. it actually tells the compiler about an entity with some meta data like name, size etc.
On the other hand, by prototype declaration for a Function means the declaration of a Function with a name and type signature without specifying the function body. So it's only for the function concept, not for variables, constants or types. And so forward declaration can be regarded as a superset of prototype declaration.
For the above example, according to definitions, it's both forward declaration and prototype declaration. Hopefully I am not wrong.

Declaring, defining, assigning, initialising variables

This is in reference to C++. This question I have goes back about 6 months, when I used to think that a declaration was:
int a;
And a definition was:
a = 5;
Also, that:
int a = 5;
was both a declaration and definition.
I've now come to understand that:
int a;
Is a definition, not just a declaration. (I don't know why).
Also, there are terms such as assigning, and initialising which add further jargon to the issue.
So here is my current understanding (and please correct anything):
int a; // Declaration and definition
int a = 5 // Declaration, definition, assignation and initialisation.
a = 5; // Initialising (if for the first time),
// assigning (if for subsequent times),
// defining (not sure about this one).
I have read quite a bit on this topic but am still confused. Can someone explain exactly what each is? I know that in such cases there are philosophical disputes, like is zero an even number, or even a number. Haha, but can someone try? Thanks.
A declaration may introduce one or more names into a translation unit or redeclare names introduced by previous declarations.
A definition is a declaration in some specific circumstance. (ie, a declaration with initializer). This is because they have to meet the One definition rule.
All definitions are declarations, but not vice-versa.
Initialization gives an initial value to a variable in its definition. Initialization will also happens in other situation (eg. function argument passing)
Assignment is used to assign a new value to an already existing object.
In your specific case
int a; // definition, default-initialization if it's local, zero-initialization otherwise
int a = 5; // definition, copy-initiaization
a = 5; // assignment
Also, the following is a declaration but not a definition
extern int i; // declaration but not definition

Why can't a typedef of a function be used to define a function?

From § 8.3.5.11 of ISO/IEC 14882:2011(E):
A typedef of function type may be used to declare a function but shall not be used to define a function
The standard goes on to give this example:
typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // ill-formed
void fv() { } // OK: definition of fv
What motivates this rule? It seems to limit the potential expressive usefulness of function typedefs.
Though this question is about C++, but since C++ inherits typedef and function pointer from C, so an explanation of the same question in C can be used in here. There's a formal explanation for C.
Rationale for International Standard - Programming Languages C §6.9.1 Function definitions
An argument list must be explicitly present in the declarator; it cannot be inherited from a typedef (see §6.7.5.3). That is to say, given the definition:
typedef int p(int q, int r);
the following fragment is invalid:
p funk // weird
{ return q + r ; }
Some current implementations rewrite the type of, for instance, a char parameter as if it were declared int, since the argument is known to be passed as an int in the absence of a prototype. The Standard requires, however, that the received argument be converted as if by assignment upon function entry. Type rewriting is thus no longer permissible.
It's probably mostly historical reasons. typedef was a relatively late addition to C, and was tacked onto the existing language (and caused a few problems for the parsing phase of compilers).
Also, a function definition has to define the names of the parameters, if any. A function type includes the function's return type and parameter types, but not its parameter names. For example, these:
void (int)
void (int x)
void (int y)
are three ways of writing the same function type. If you had:
typedef void func_t(int);
then this hypothetical definition:
func_t some_func { }
wouldn't define a name for its int parameter. I'm not sure how that could have been resolved in a reasonable manner. It would be possible, I suppose, but it was never done.
But the bottom line is probably just that Dennis Ritchie either didn't think it was worth the effort to define how a typedef could be used in a function definition, or he simply didn't think of it.
Let me put a few words. Consider a statement:
typedef void F(int p1, char* p2);
This statement assigns name F to a function signature void (int, char*); This is definition of an alias to the function signature. After that the statement:
F fv;
tells that there is a function fv. It has the signature that was mentioned above and it has its body somewhere. Look at the C/C++ syntax of the function definition:
retType funcName(params) { body }
There are actually 2 names used retType and funcName. None of them are the same to the name F from the initial typedef. The name F has meaning of both names. If language would allow something like:
F { body }
this will associate body with the function type. But this leads a problem:
The meaning of F would be not clear. Is it an "alias to the function signature" or is it a "name of the entry point into a code"?
Plus the syntax of the last example would be weird to millions of C/C++ programmers.
The rule is as you quoted - typedef of function type shall not be used to define a function. In the 3rd line of the example, you are trying to define a function with function type F. This is not allowed by the standard.
EDIT
As you pointed out, I try to explain more on it.
For the 3rd line, if it were legal, then you could replace F with the typedef definition:
void fv { }(). This is not a legal definition or declaration in C++.
I think the key point is that typedef is just creating an alias for simplification, and you can replace your typedef type like replacement of #define during compilation.