Isn't void in int main(void) redundant? [duplicate] - c

This question already has answers here:
in c: func(void) vs. func() [duplicate]
(2 answers)
Closed 7 years ago.
The C99 standard document I have clearly states that
6.7.5.3.14 An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters. The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied.
What I interpret from that sentence is that writing void in function definition is redundant. Did I get it correctly?

No, you're slightly wrong.
void specifies that there is abosolutely no arguments passed.
empty parenthesis () indicates that the function can be called with any number of arguments, without generating a warning.
Note: Remember, there is no prototype defined or supplied by the implementation for main().
Maybe, C11 standard, chapter 5.1.2.2.1, describes it better way,
The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }`
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;10) or in some other implementation-defined manner.

Related

Is int main(void) { } a prototype?

I'm trying to understand declarations, definitions and prototypes. I came across the excellent post https://stackoverflow.com/a/41805712/1825603. I do, however, need some clarification, but because I do not have enough reputation to comment directly to the post, I will ask here...
The relevant section:
In definitions
void func1() { } // obsolescent
and
void func2(void) { }
The former declares and defines a function func1
that has no parameters and no prototype
The latter declares and defines a function func2 with a prototype that
has no parameters.
When I see int main(void) { } as one of the Standard definitions for main in C99 5.1.2.2.1, I interpret from the above that it's "a declaration and definition of a function with a prototype that has no parameters". My confusion lies with C99 5.1.2.2.1, where it says, "The implementation declares no prototype for this function." By adding the void to int main() { }, does this mean the user-level code is declaring a prototype because the implementation hasn't? And if it's not a prototype, what is the effect of adding void?
Note: I believe I understand the reason the declaration int main(void); isn't used, ie, Declare main prototype, but don't think my question is a duplicate of this.
C 2018 6.2.1 2 says:
… ((A function prototype is a declaration of a function that declares the types of its parameters.)
Thus int main(int argc, char *argv[]); is a function prototype, because it declares the types of its parameters, argc and argv.
int main(int argc, char *argv[]) {} is also a function prototype. Even thought it is a function definition, it also declares the function.
Functions can be defined with an old style that did not have declarations in the parameter list, such as:
int main(argc, argv)
int argc;
char *argv[];
{
}
Although the types of the parameters are declared in the declaration list between the function declarator and the body of the function, this is not what the C standard means by declaring the types of the parameters. This phrasing in the C standard is unfortunately imprecise, but the intent is that a “function prototype” is a declaration of the modern form with the types specified in the parameter list, contrasted with the legacy form with only the parameter names in the list.
We can see this because C 2018 6.2.7 3 distinguishes a function prototype as a function declared with a parameter type list rather than a simple identifier list:
… a function type with a parameter type list (a function prototype)…
Also note the special form (void), as in int foo(void), counts as a function prototype as a special case; it is the modern form of declaration that asserts the function has no parameters. The old form int foo(); does not specify whether the function has parameters or not.
Is int main(void) { } a prototype?
Yes.
int main(void) { } is a function declaration and definition. As a declaration, it says nothing about the parameters. As a definition, it takes no parameters: i.e void.

Is this syntactically correct C code? [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 4 years ago.
I am just starting to learn C and am bit confused about use of return statement and its importance in C language.
Here's my code snippet. Is this syntactically correct or do we have to return any numerical value 0 or 1 while using int main()?
#include<stdio.h>
int main()
{
int i;
for(i=0;i<10;i++)
printf("\n Noooooooooo");
return ;
}
Per the C 2011 standard (draft N1570), clause 6.8.6.4, paragraph 1:
A return statement without an expression shall only appear in a function whose return type is void.
Your return statement does not have an expression and appears in the main function whose return type is int, not void. Hence your program violates the constraint.
First of all let's clarify that because you refer to the main function, obviously (but not for all seems) this answer assume that you are referring to an hosted environment, because for a freestanding environment (see ISO/IEC 9899:2011 "§5.1.2.1 Freestanding environment") there are no requirements at all and the name and type of the function called at program startup are implementation-defined.
Going back to the hosted environment, the standard that defines C language, in its more recent version ISO/IEC 9899:2011, for C11, describe the requirements for the program startup function in an enough strict way (§5.1.2.2.1 Program startup).
The points to be respected are essentially:
The main function must return an int.
Only 2 variation of it are allowed:
Without parameters as in : int main(void) { /* ... */ }
With 2 parameters a count of argument elements and the array of arguments as in : int main(int argc, char *argv[]) { /* ... */ }
Some implementation variation are allowed, but only as different representation of same parameters (i.e. instead of char *argv[] the equivalent char **argv, or some typedef for specific types resolving in an int type for argc).
The very common definition void main() { /* ... */ } allowed in some major compiler producers (most often MS) are not strictly C99-C11 compliant.
In fact the use of empty parenthesis in function declarators is an obsolescent feature that could be removed in future standard revision as reported in "§6.11 Future language directions" (thanks to have reported me the imprecision). In fact many compilers C99-C11 compliant issue a warning.
So considering the before mentioned obsolescence would be a good habit to use a more standard declarations.
In conclusion your declaration is wrong because:
return; You return no value
Optionally consider that main() miss the void (strict C99-C11)
What you return depends on what you want return. Let only say that a general convention commonly accepted is to return from main the value 0 (zero) for normal termination (no errors), any other value denotes an execution error.
Anyway for the sake of precision, for those who want go inside specs, I report below the exact text from specific paragraph
5.1.2.2.1 Program startup
The function called at program startup is named main.
The implementation declares no prototype for this
function. It shall be defined with a return type of int (emphasis mine, please see below the definition of the term shall in ISO document) and with no
parameters:
int main(void) { /* ... */ } or with two parameters
(referred to here as argc and argv, though any names may be used, as
they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;(see note below) or in some other implementation-defined manner.
The note for equivalent type says:
NOTE: Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on
Last to remove any doubt about the meaning of the term "shall" the ISO/IEC 9899:2011 specification clearly define it on paragraph §4.0 Conformance at subpar. 1:
4.0 Conformance
1 In this International Standard, ‘‘shall’’ is to be interpreted as
a requirement on an implementation or on a program; conversely,
‘‘shall not’’ is to be interpreted as a prohibition.

"Return type of main is not int" warning on macOS [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 5 years ago.
So I have a MacBook Pro 2017 and whenever I compile a program that as "void main", the compiler gives me a warning saying that the return type of main is not int...
void main(){
(...)
}
Like the warning says, you should define the return type as an int:
int main() {
// bunch of code...
return 0;
}
Current versions of the C standard require that the main function has a return type of int. So you need to change the definition to int main() and have it return a value.
Section 5.1.2.2.1 of the C standard detailing hosted environments states the following:
1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent or in some other implementation-defined manner.
Note that a definition of int main() is allowable as the empty parameter list means the function takes no parameters. From section 6.7.6.3:
14 An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator
that is part of a definition of that function specifies that the
function has no parameters. The empty list in a function declarator
that is not part of a definition of that function specifies that no
information about the number or types of the parameters is supplied.
Specifying the main function as void main() is a pre-standardized variant from the K&R days and is no longer valid.
It's expected that main() will return an int value. A minimal start is:
int main() {
return 0;
}
A more formal version which accepts command-line parameters:
int main(int argc, char** argv) {
return 0;
}
Declaring it with a different type makes it incompatible. Some older compilers may not care, but Xcode's does.
C has been around a long time and has evolved considerably from its early days. If you're using an older reference you may find examples with really strange notation, or conventions that are no longer value.

main function with respect to C [duplicate]

This question already has answers here:
Non-standard signature of main() compiles successfully
(4 answers)
Closed 9 years ago.
5.1.2.2.1 Program startup
The implementation declares no prototype for this function. It shall be defined
with a return type of int and with no parameters.
I have defined like this,
int main(int a, int b, int c){.......}
It works. I didn't understood the first line "The implementation declares no prototype for this function"
Need help, Thanks
All it means is that main is not declared in advance. There's no line like
int main(int argc, char*argv[]);
and that means that when you define the function, you can pretend it takes any arguments and returns any type you like without getting a compiler error.
Of course, main is called by the operating system, so it will expect your definition to match whatever convention it uses for passing parameters. In practice, except on embedded systems, your definiton for main has to match the above.
When you are making a prototype then it means that you want to call it elsewhere which is not the case for main function.
From the docs:-
5.1.2.2.1 Program startup
1 The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;9) or in some other implementation-defined manner.
declaration or prototype is not require for main function
functions other than main requires declaration and
definition
int sum(int,int); //declaration
int sum(int a,int b) //definition
{
//body
}
You left out the rest of the quote from that section of the standard, I am going to quote the C99 draft standard which says:
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;9) or in some other implementation-defined manner.
The shall be defined is the quote is the important part, it says it must follow one of these two signatures or if available some implementation specific signature which would be defined by the compiler implementor.
If I attempt to build this in the latest version of clang I see the following errors:
error: second parameter of 'main' (argument array) must be of type 'char **'
int main(int a, int b, int c){}
error: third parameter of 'main' (environment) must be of type 'char **'

What does main() return? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What should main() return in C/C++?
What value does this function return. just plain main.
main()
{
...
}
and if a function has two mains , what happens?
What value does this function return.
main needs to be declared as returning an int. The return value is passed to the caller, which is usually the operating system.
5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
and if a function has two mains , what happens?
Linker reports an error.
In C99/C11, main returns 0 if the } is reached in a hosted environment,. Else, the return value is undefined.
C11, § 5.1.2.2.2 Program execution
[...] reaching the } that terminates the main function returns a value of 0.
Assuming you're using a C89 or earlier compiler, then
main()
{
...
}
returns int. If you're using a C99 or later compiler, it's an error.
As of C99, if you reach the ending } of main without an explicit return, the return value is 0. Not sure about C89 or earlier.
Not sure what "a function has two mains" is supposed to mean. If a program has two main functions defined, then you'll most likely get a duplicate definition error at link time.

Resources