main function in C with void and without void [duplicate] - c

This question already has answers here:
func() vs func(void) in C99
(4 answers)
Difference between int main() and int main(void)?
(10 answers)
Closed 4 years ago.
What is the difference between these two programs?
The 1st one i am getting 4,3,2,1 and 2nd one is compilation error.
#include <stdio.h>
int main()
{
static int i = 5;
if (--i){
printf("%d ", i);
main(10);
}
}
and
#include <stdio.h>
int main(void)
{
static int i = 5;
if (--i){
printf("%d ", i);
main(10);
}
}

When you define a function like this:
int func() { ... }
It says that the function takes an indeterminate number of arguments and returns an int. So you can legally pass any number of arguments of any type (although you won't be able to access them).
When you define a function like this:
int func(void) { ... }
It says that the function takes no arguments. Attempting to pass any arguments to this function will result in a compile time error.
On a side note, recursively calling the main function is not a good idea. You're better off either calling another function which is recursive or just using a loop.

The appearance of a solitary void in a parameter list explicitly tells the compiler "this function takes no arguments".
In the first code example, calling main recursively is permitted since there is no argument list, which permits any number of arguments (this may have been changed in a more recent C standard than the one supported by your compiler; I forget the specifics).
Variables declared static are stored in the process' data section rather than in stack memory, so they persist beyond their scope and retain their value across function calls, so i decrements on each call until it reaches zero and your program hits the base case (don't enter the if statement), and terminates.

Related

The external (global) variables in C

I'm reading a C programming book, The C Programming Language (K & R, 2nd Edition). I got to know the facts about external variables in the book, but I found something different when I practiced the principles by myself. The book says:
"... because external variables remain in existence permanently, rather than appearing and disappearing as functions are called and exited, they retain their values even after the functions that set them have returned."
However, when I code like this:
#include <stdio.h>
int i = 0;
void foo();
main()
{
foo();
printf("%d", i);
return 0;
}
void foo()
{
i = 1;
}
The program prints 1 instead of 0 which is the original value of the external variable i. So I wonder where I get mistakes while thinking about the principle and how to understand it.
...they retain their values even after the functions that set them have returned.
I'm guessing it's a question of interpretation on your part.
Given that the variable is global, every time you change it, in any function, it will assume and retain that value until it is next modified.
Take the function:
int i = 0;
void foo();
int main()
{
int x = 0;
foo(x);
printf("%d", i);
printf("%d", x);
return 0;
}
void foo(int x)
{
x = 1;
i = 1;
}
result: x = 0 i = 1
x is passed by value, essentially, a copy of it, so as soon as the function goes out of scope, i.e. returns, the copy is discarded. i is global so you don't even need to pass it; every function is aware of its existence and will change its value.
Opposite to what you think this phrase
...as functions are called and exited, they remain their values even
after the functions that set them have returned
means that after exiting a function a variables with the external linkage keeps the value assigned to it in the function. And your program demonstrates this.
Pay attention to that now according to the C Standard the function main without parameters shall be declared like
int main( void )
There is no default type int of a function though some compilers keep the backward compatibility.

C - Should a function return something especially in main() declaration? [duplicate]

This question already has answers here:
Can I omit return from main in C? [duplicate]
(2 answers)
Why do C standards allow you not to return a value from a function?
(5 answers)
What was the rationale for making `return 0` at the end of `main` optional?
(2 answers)
What should main() return in C and C++?
(19 answers)
Closed 3 years ago.
Which is a good practice of int main() declaration in C?
int main(){
stuff;
return 0;
}
or
int main(){
stuff;
}
I have tried searching on the internet and most of them are unclear with some mentioning about compiler stuff. I know that a function should return something. However, both works perfectly normal on my computer. Any help on this topic will be greatly appreciated.
Because many programmers used the second style, causing unspecified exit status to be reported to the system, the C Standard committee decided to make main return 0 implicitly if control leaves its body without a return statement. This behavior is mandated by the C Standard C99 and later versions. As a consequence, return 0; can be omitted by it is better IMHO to still make it explicit.
Note however that it is also considered good style to indent the statements in the body of functions:
int main() {
stuff;
return 0;
}
Note also that the C Standard documents 2 possible prototypes for main:
int main(void);
and
int main(int argc, char *argv[]);
or equivalent variants:
int main(int argc, char **argv[]);
int main(const int argc, char ** const argv);
etc.
Omitting the argument list as you wrote in both examples is supported and would be equivalent to int main(void) in C++, but is not exactly equivalent in C: It means the argument list is unspecified, so the compiler cannot check the arguments passed to main if it encounters a call to main in the program, not can it perform the appropriate conversions.
In this case, it does not matter since the main functions in the examples do not use their arguments and indeed seems more consistent than int main(void) since arguments are indeed passed to it by the startup code.
Both will work, because main is special. There's no difference in the compiled code. The standard guarantees that main returns 0 if it terminates without an explicit return value.
But it's better to be explicit and return 0.
For skeptics, an excerpt from the C standard clause 5.1.2.2.3 (Program termination):
a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0.
Normally it is not allowed for the control flow to reach the end of a non-void function without returning something. The main function is handled differently.Refer the below document page 59 & 62
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2960.pdf:
If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

Catching variables passed to function with no arguments

I don't know if it's possible but the wikipedia article here Compatibility of C and C++ says the following :
In C, a function prototype without arguments, e.g. int foo();,
implies that the parameters are unspecified. Therefore, it is legal to
call such a function with one or more arguments, e.g. foo(42, "hello
world").
In contrast, in C++ a function prototype without arguments
means that the function takes no arguments, and calling such a
function with arguments is ill-formed.
In C, the correct way to
declare a function that takes no arguments is by using void, as in
int foo(void);.
I made the following code to test it and catch the passed variables (which doesn't work quite right)
#include<stdio.h>
#include<stdarg.h>
void foo();
int main()
{
int i = 3;
foo(i);
return 0;
}
void foo()
{
// va_list args;
// va_start(args);
//
// int x = va_arg (args, int);
// printf("%d", x);
// va_end(args);
}
Is it possible to catch the passed i or is Wikipedia talking about something completely different?
You can't, at least not in standard C. What the Wikipedia article means is this code:
void foo();
int main()
{
int i = 3;
foo(i);
return 0;
}
void foo(int i)
{
(void)i;
}
Compiles fine in C, but it's invalid in C++ because the number of arguments don't match.
If you read the documentation for va_start you will see that it needs the last "real" argument in the argument list. So it's not possible in plain C to get the arguments if you don't declare any arguments.
What you can do is to declare the function prototype without arguments, and have arguments in the actual definition.
That comes from the old C days when the strictness of the language was, well..., relaxed.
The basic idea was that if you had a function in a translation unit, say foo.c:
float foo(int x)
{
return 2.0F * x;
}
And then you want to use it in another translation unit, say main.c but you don't want to bother with writing a header file, you could just do:
int main()
{
float foo();
float r;
r = foo(42);
}
And you don't have to write the arguments of the function. To be fair, you didn't have to write the prototype at all, but then the compiler would assume that the function always returns int which may not be what you need.
Then, as the language matured, this kind of function declaration was decided to be a very bad idea, so generally speaking you should not (try to) use it. If you want a variadic function, then by all means use it, but declare it as such. And you have to give it at least a real argument, to anchor the call to va_start().
You can call the function with any arguments, but you can't access them in the function scope. Anyway some compilers will give you warnings if you don't declare the prototype as int foo (void); since you probably don't want to do this anyway.
There is a way to access those parameters in C program, but I look at it as a big hack, which should be avoided.
Next example shows how to access an int parameter :
#include<stdio.h>
#include<stdarg.h>
void foo();
int main()
{
int i = 3;
foo(i);
return 0;
}
void foo(int p)
{
printf("%d",p);
}
Now, I am not sure what happens if you pass something else then int (for example char*), but it may cause an undefined behavior.
In c++ (as said), you can not pass parameters to functions taking no parameters.

What's the use case of foo() meaning foo has an unknown amount of arguments? [duplicate]

This question already has answers here:
int foo (int argc, ...) vs int foo() vs int foo(void) in C
(4 answers)
Closed 9 years ago.
So I was recently reading a bit on Hacker News about function pointers and was enlightened to the fact that void foo() and void foo(void) are NOT equivalent prototypes. So, I set about ensuring that this is actually true:
int foo()
{
return 0;
}
int main()
{
return foo(1,2,3,4);
}
Sure enough, this code compiles without even so much as a warning.. where as this code will throw an error:
int foo(void)
{
return 0;
}
int main()
{
return foo(1,2,3,4);
}
This seems very error prone. I also thought that ... for "any amount of arguments", such as in printf's signature
int printf ( const char * format, ... );
Was this also true in C89 or K&R? Can anyone give insight into the use case for this "feature"?
It's not really a "feature", per se. It's just the way the language used to be back in the beginning, so the syntax has lived on to keep old code working. The addition of void made it possible to have functions that explicitly took no arguments, for example.
The use of the ... indicates a variadic function, which is subtly different from a function that just takes an arbitrary number of arguments, though. Using the ... requires the use of stdarg.h macros, but just having a function declared with () doesn't.

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