c void main function? returning 16 value - c

I am writing a c program with void main function in code blocks.
I just write return with no value.
The program is as below:
#include<stdio.h>
void main (void)
{
printf ("ali tariq\n");
return;
}
However, in the console window the program returns the value 16 in the console window. "Process returned 16"
I want to know why it is returning this value?
How can i utilize this value in windows using codeblocks?
Thanks

In (hosted) C the main function must return an int (C11§5.1.2.2.1[1]). By declaring it with a return type of void, and not specifying any return value you invoke undefined behaviour. This means the compiler is free to return anything and in your case it turns out to be 16.

You are not free to declare the return type of main as you wish. Why?
BECAUSE YOU DIDN'T WRITE THE CODE CALLING main(). Sorry 'bout the shouting, but someone else wrote that code and placed it in crt0.o or so. Your main() is linked against that code and it can't just return what it wants because that code expects an int. Always. It's already written and compiled. You understand this subtle point?
Because the C Standard says so. See other answer by Kninnug for Chapter and Verse.
In other words, your code invokes undefined behavior and it should be no surprise to find a garbage value where no value was provided.
So you expected a warning from the compiler? The better ones indeed will catch this with the right options. E.g. gcc and clang support -Wmain-return-type.

You should not use void main(), use int main() instead.

The program has undefined behavior. First of all according to the C Standard main without parameters shall be declared like
int main( void )
You declared the function as having return type void. In this case the process that starts the program can not get a valid return code of the program.

Just because a function is declared as void doesn't mean it won't return anything. On the x86, for example, a lot of calling conventions specify that the value in the register EAX after a function call is the return value of the function. So, if you have a C function that is declared void but the machine code for the function changes the value of EAX, that will get treated as the return value for the function.

EVERY "normal" program that terminate execution WITHOUT errors, must return ZERO.
So, your program must be:
#include<stdio.h>
int main (int argc, char *argv[]) // your program may have command line parameters
{
printf ("ali tariq\n");
return 0; // Program terminate with NO ERRORS
}
However there are cases when one program may terminate WITH errors.
Let's suppose this:
#include<stdio.h>
void main (int argc, char *argv[])
{
// program to make a division between two numbers
double a, b, res;
a = b = res = 0.0;
printf ("Enter 1st number: ");
scanf ("%lf", &a);
printf ("Enter 2nd number: ");
scanf ("%lf", &b);
if (b == 0) return 1; // division by '0' then return ERROR (any number != 0)
printf ("%f / %f = %f", a, b, a/b);
return 0; // NO ERROR
}
Now you may ask: «But where is the return value evaluated?
Answer: «By the Operating System.»
One batch file may run your program and read the integer YOU returned in the environment variable 'ERRORLEVEL'

Related

In this case i want to undestand, why is the output 10 instead of 20?

i want to understand why output in this code is 10 not 20
#include<stdio.h>
#include <stdio.h>
int check (int, int);
int main()
{
int c;
c = check(10, 20);
printf("c=%d\n", c);
return 0;
}
int check(int i, int j)
{
int *p, *q;
p=&i;
q=&j;
i>=45?*p:*q;
}
The problem here is that the return value of the check() function is undefined behavior.
In order to get the expected output of 20 you would have to use the return statement like this return i>=45?*p:*q;
You need to do this to actually tell the compiler to write the result to the return register.
If you don't do this the function simply exits without explicitly writing the result value to the return register. Instead the register content is simply left in the state it was last in (in your case 10), but this is in no way guaranteed and will very likely vary with the compiler used.
If you really want to understand it on an instruction level have a look here: godbolt compiler explorer
There on the right you can see the x86 assembly of your program, and if you look closely you can see that the compiler just so happens to use the eax register to compare the value which is also by ABI convention the register used for function return values.

Confused about detecting the errors of this code in c programming language?

The code given below is an exercise that our teacher gave to prepare us for exams.
We are supposed to find the errors that occur in this code and fully explain them .
#define SIZE 10
int start (void a,int k) {
const int size=10;
char array[size];
char string[SIZE];
mycheck(3,4);
array[0]=string[0]='A';
printf("%c %c\n", array[0], string[0]);
myRec(7);
}
int mycheck(int a , int b) {
if (a==0 || b==0 ) {
return 0;
}
else {
return (a*b);
}
}
int myRec(int x) {
if(x==0)
return 0;
else
printf("%d,",x);
myRec(x--);
}
I have found these errors so far:
1.int start (void a,int k)
explanation: We can't have a variable of type void, because void is an incomplete type
2.const int size=10;
explanation:we can't use variable to define size of array
(problem is when I run it in dev-c++ it doesn't show an error so I'm not sure about this)
3.mycheck(3,4);
explanation: prototype of function mycheck() is not declared, so the function mycheck is not visible to the compiler while going through start() function
4.A friend told me that there is an error in function myRec because of this statement myRec(x--);
(I don't really get why is this an error and how you can I explain it?)
5.Main() function doesn't exist.
I'm not sure about this but if i run the code (in dev-c++) without main function I get a compilation error
I'm not sure if the errors that I pointed out are 100% right or if I missed an error or if I explained them correctly.
Please correct me if any of the above is wrong!
a friend told me that there is an error in function myRec cuz of this
statement myRec(x--);
It will lead to stackoverflow. Due to post-decrement, the actual argument passed to function myRec(), never decreases and therefore the condition:
if(x==0)
return 0;
will never become true. Regarding your rest of the errors, it depends on the compiler version being used:
For example C99, you are allowed to have variable size arrays like this:
const int size=10;
char array[size];
char string[SIZE];
but pre C99, you would have to use malloc or calloc. For your functions used without prototype, most compilers would generate a warning and not error and also due to no #include<stdio.h> statement, your printf would also lead to a warning.i Again, lot of these things are compiler dependent.
1.int start (void a,int k)
explanation: We can't have a variable of type void ,because void is an
incomplete type
Correct.
2.const int size=10;
explanation:we can't use variable to define size of array (problem is
when i run it in dev-c++ it doesnt show an error?so im not sure about
this!)
This is also correct, that char array[size];, where size is not a compile-time constant, is invalid in C89. However, in C99 and newer, this is actually valid and would create a variable-length array. It is possible that your Dev-C++ IDE is using GCC with the language set to C99 or newer, or has GNU C extensions enabled to enable this feature.
3.mycheck(3,4);
explanation: prototype of function mycheck() is not declared.So the
function mycheck is not visible to the compiler while going through
start() function
Correct. This can be fixed either by declaring the function's prototype before the start() function, or just moving the whole function to the top of the file. As noted by Toby Speight in the comments, in C89, this should not actually be a compiler error, since functions are implicitly declared when they are used before any actual declaration as int (), i.e. a function returning int with any arguments, which is compatible with the declarations of mycheck and myRec. It is however bad practice to rely on this, and implicit function declaration does not work in C99 or newer.
4.a friend told me that there is an error in function myRec cuz of this statement myRec(x--);
(I don't really get why is this an error and how you can explain it?)
This function is a recursive function. This means it calls itself within itself in order to achieve a kind of looping. However, this function as it is currently written would run forever and cause an infinite loop, and since it is a recursive function, and needs a new stack frame each time it is called, it will most likely end in a stack overflow.
The function is written with this statement:
if(x==0)
return 0;
This is intended to terminate the recursion as soon as x reaches 0. However, this never happens, because of this line of code here:
myRec(x--);
In C, postfix -- and ++ operators evaluate to their original value before the addition or subtraction:
int x = 5;
int y = x--;
/* x is now 4; y is now 5 */
However, using the prefix version of these operators will evaluate to their new value after adding / subtracting 1:
int x = 5;
int y = --x;
/* x is now 4; y is now 4 */
This means that on each recursion, the value of x never actually changes and so never reaches 0.
So this line of code should actually read:
myRec(--x);
Or even just this:
myRec(x - 1);
5.Main() function doesn't exist ...again im not sure about this but if i run the code (in dev-c++) without main function i get a compilation
error
This one could either be right or wrong. If the program is meant to run on its own, then yes, there should be a main function. It's possible that the function start here should actually be int main(void) or int main(int argc, char *argv[]). It is entirely valid however to compile a C file without a main, for example when making a library or one individual compilation unit in a bigger program where main is defined in another file.
Another problem with the program is that myRec is used before it is declared, just like your point 3 where mycheck is used before it is declared.
One more problem is that the functions start and mycheck are declared to return int, yet they both do not contain a return statement which returns an int value.
Other than that, assuming that this is the entire verbatim source of the program, the header stdio.h isn't included, yet the function printf is being used. Finally, there's the issue of inconsistent indentation. This may or may not be something you are being tested for, but it is good practice to indent function bodies, and indentation should be the same number of spaces / tab characters wherever it's used, e.g.:
int myRec(int x) {
if(x==0)
return 0;
else
printf("%d,",x);
myRec(x--);
}
1) Hello friend your Recursive function myRec() will go infinite because it
call itself with post detriment value as per C99 standard it will
first call it self then decrements but when it call itself again it have
to do the same task to calling self so it will never decrements and new
stack is created and none of any stack will clear that recursion so
stack will full and you will get segmentation fault because it will go
beyond stack size.
2) printf("%d,",x); it should be printf("%d",x); and you should include #include library.
I think your another mistake is you are calling your mycheck() and you
returning multiplication of two integer but you are not catch with any
value so that process got west.So while you are returning something you
must have to catch it otherwise no need to return it.
3) In this you Program main() function missing. Program execution starts
with main() so without it your code is nothing. if you want to execute
your code by your own function then you have to do some process but
here main() should be present.or instead of start() main() should
be present.
4) you can also allocate any char buffer like this int j; char array[j=20];
your code should be like this.
#include<stdio.h>
#define SIZE 10
int mycheck(int a , int b) {
if (a==0 || b==0 ) {
return 0;
}
else {
return (a*b);
}
}
int myRec(int x) {
if(x==0)
return 0;
else
printf("%d",x);
myRec(--x);
}
void main (int argc, char** argv) {
const int size=10;
char array[size];
char string[SIZE];
int catch = mycheck(3,4);
printf("return value:: %d\n",catch);
array[0]=string[0]='A';
printf("%c %c\n", array[0], string[0]);
myRec(7);
printf("\n");
}
Enjoy.............

What happens when you call a function with return value without assigning it to any variable?

#include <stdio.h>
#include <stdlib.h>
int f(int x) {
return x;
}
int main ( int argc,char * argv[]) {
int a=4;
f(a);
printf("PASSED!\n");
return 0;
}
What happens when you call f(a) without assigning it to anything?
What happens when you call a function with return value without assigning it to any variable?
The return value of a function need not be used or assigned. It is ignored (usually quietly).
The function still executes and its side effects still occur.
Consider the 3 functions: int scanf(), int f(), and int printf(), their return values are all ignored yet the functions were still executed.
int a=4;
scanf("%d", &a);
f(a);
printf("PASSED!\n");
It is not good to ignore return values in robust code, especially scanf().
As commented by #Olaf, a warning may be enabled by some compilers.
Explicit ignoring the result of a function is sometime denoted with (void) to quiet that warning.
(void) f(a);
Using your example, we can look at how it evaluates line by line. Starting in main.
int a=4;
We now have a variable a with the value 4.
f(a);
So now the function f is called with a, which has a value of 4. So in the function f, the first parameter is named x and it just returns that parameter x.
So the evaluation of
f(a);
is just
4;
And a program like this compiles and runs perfectly fine.
int main(int argv, char *argv[]) {
1 + 1;
return 0;
}
What happens when you call f(a) without assigning it to anything?
--> Nothing at all.
What happens when you call a function (which has return value) without assigning it to anything?
-->The function will be executed, either make no sense like your case or make a lot of senses like modifying a static variable or a global variable. The return value will be ignored.
The return value will normally be stored in a register and will not fade.
It will be overwritten when the register is needed by the compiler.
If the function is inline it may be detected by the compiler that the value isn't used and ignore the value from being computed at all.

Simple C program that will read the number of lines and will terminate once the EOF is entered by the user

#include <stdio.h>
int read_next_line()
{
int ch;
int flag=0;
ch=getchar();
while(ch!= EOF && ch!='\n') {
ch=getchar();
flag=1;
}
return flag || (ch=='\n');
}
int read_all_lines()
{
int linecount=0;
int isvalid;
while(!feof(stdin)) {
isvalid=read_next_line();
linecount=linecount + isvalid;
}
return linecount;
}
main {
read_all_lines();
}
The above code gives an error saying main does not have a type.
How to solve the problem ?
main is a function that returns a value like other functions. It is up to you if it returns nothing void main(void){ } or an int value, 0 is returned in POSIX systems if no error encountered. More sophisticated but readable is to put exit(EXIT_SUCCESS);.
int main(void){
...
}
The proper prototype in most environments is:
int main(int argc, char *argv[])
This means:
main() is a function that returns an int.
It has one argument called argc that is the number of command-line arguments.
It has one argument called argv that is an array of those arguments.
It should be int main() instead of simply main
Since C98 I think, C disallows to declare a function without using the return type for the result anymore. You have to declare main as
int main ()
{
...
}
This is the minimum requirement to make your code compilable. In previous releases of the C language, it was allowed to declare a function like you have done. Implicitly, the compiler assumed it to be an int function without any complaint. But, as for sure you have your compiler configured to compile post C98 or later code, it complaints with an error. Previous versions of actual compilers issue normally a warning, telling you main will be assumed to be an int function, and this is to be able to compile old pre-ANSI code.
By the way, next time, don't limit yourself to explain what you have coded. Cut and paste your actual code here, and also the exact error you got from the compiler (probably, it was only a warning, but you didn't include it, so we'll never know) Probably the mistake is not where you think of, and that way saves us time and you the need of receiving this complaint.

De-Referencing a pointer passed from another function to main()

I'm trying to use a separate function to input data using scanf() (outside of main). This new function is supposed to print a line and then receive input from the user. However something appears to be going awry between the scanf in the function and the printf() function in the main that I am testing it with.
I believe that I am receiving a pointer from the function but certain compiler warning are making me wonder if my assumption about the pointer is even correct.
I am confused by the output of this code:
#include <stdio.h>
void set_Info(void);
int main()
{
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
return 0;
}
void set_Info(void) /* start of function definition */
{
int scanNum;
printf("Scan test, enter a number");
scanf("%d",&scanNum);
}
If I provide a number, say 2, the result of the printf statement in the main() is:
2665560
Now, in so far as I am able to tell that output appears to me like a memory address so what i attempted to do to fix that is dereference the pointer in main like so :
int scanNum = 0;
int scanNumHolder;
set_Info();
scanNumHolder = *scanNum;
printf("%d", &scanNumHolder);
I believe that this code makes scanNum variable to become assigned to the dereferenced value of scanNum. However I get the same output as above when I do this. Which leads me to believe one of two things. Either that I am not correctly dereferencing scanNum, or that scanNum is not in fact a pointer at all in this situation.
The most common error I receive from the compiler is:
error: invalid type argument of unary ‘*’ (have ‘int’)
Which makes sense, I suppose, if I'm attempting to treat an int value as a pointer.
If it is the case that scanNum is not being dereferenced correctly, how can I achieve this?
Thank you for the help
*Update
Thanks for the help.
Just to recap
My set_info function needs to be passed an address parameter. The reason an address parameter has to be used is because the local memory of a function is erased after the function call ends. So in order to do work a variable declared in the main function, I pass the address of the variable in question so that when the function ends the changes are not lost.
Inside the main function, when set_info is called with &scanNum as the argument, it passes a reference tp the variable so that it can be assigned the value generated by the scanf statement in the function.
I realize that what I was doing wrong as correctly pointed out by the awesome people of SO, is that I am trying to call set_info like it returns a value but in fact changes the variable like I actually want.
Thanks again for the help!
This function:
void set_Info(void)
{
int scanNum;
scanf("%d", &scanNum);
}
reads the integral number from the standard input and stores it into scanNum variable, which is local variable with automatic storage duration that exists only within the scope of this function.
And the body of your main:
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
defines a local variable called scanNum, then calls a set_Info() function which doesn't affect scanNum defined in main in any way and then it prints the address of scanNum variable.
This is what you are trying to do:
void set_Info(int* num)
{
// read an integer and store it into int that num points to:
scanf("%d", num);
}
int main()
{
int scanNum = 0;
// pass the address of scanNum to set_Info function so that
// changes to scanNum are visible in the body of main as well:
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
I also recommend you spend more time reading some book with C basics before you'll continue programming :)
I would pass in the variable into your set_Info function, so that it knows where to save the data. This would then allow you to scan multiple values, and you would simple increment the pointer. Be sure to pass the variable address into set_Info() using &variableName, since that function expects a pointer
#include <stdio.h>
void set_Info(int *pScanNum);
int main()
{
int scanNum = 0;
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
//Pass in the pointer to scanNum
void set_Info(int *pScanNum)
{
printf("Scan test, enter a number");
scanf("%d",pScanNum);
}
Get rid of your ampersand! Printf wants an integer not a pointer.
printf("%d", scanNum);
And as liho said, you need to return scanNum from set_info so you can get at it outside of the function.
int scanNum = set_Info();

Resources