I am trying to print the value of a local variable inside of main, from another function without using global variables. What would be the best way to do so?
#include <stdio.h>
int function1();
int main(void) {
int hello=10;
printf(function1());
}
int function1(int ip){
printf("hello%d",ip);
}
I am expecting the 10 to be printed next to the "hello" but instead get a 0.
You need to call the function passing the value (or variable) required.
int function1(int);
int main(void)
{
int hello=10;
function1(hello);
function1(130);
}
int function1(int ip)
{
return printf("hello - %d\n",ip);
}
https://godbolt.org/z/97o3dPWzj
change
int function1();
to
int function1(int);
and
printf(function1());
to
function1(hello);
"I am expecting the 10 to be printed next to the "hello" but instead get a 0."
There are already examples of working versions of your code in the other answers, but little is said in the way of explanation. I will try to do that here, and offer some general suggestions.
Although your code compiles, it does so with warnings and when run, produces run-time errors. The information resulting from both of these, if heeded would likely provide a guide to addressing most of your issues. (If using GCC for example, you can set warnings to -Wall). To illustrate, here is an image showing line numbers and the warning that correspond with them on my system (not GCC, but warning are turned on)
Build warnings:
And finally, run-time error:
From these you can begin to derive some of the following observations (others listed are my own.)
The signature of a function prototype must match its implementation. (for function1, they do not)
If the prototype of a function is non-void, then it should return a value.
If a function returns a value, its return value should not be ignored.
The warning of an unused variable pointed out that you probably intended to use it as an argument here: function1()
See comments below for other clarifications:
int function1();//this prototype is incomplete, and is inconsistent
//with the signature of its implementation
int main(void) {
int hello=10;
printf(function1());//because function1 is not returning a value, your code outputs a 0
//Function1 prototype requires it to pass an argument
// non-void function should return a value here
}
int function1(int ip){//signature of this implementation disagrees with its prototype
//because there is no value passed, ip can be any value
printf("hello%d",ip);
// non-void function should return a value here
}
Related
Consider,
#include<stdio.h>
int main()
{
int y = facto(6);
printf("%d",y);
return 0;
}
int facto(int x)
{
if(x==1)
return 1;
else
return x*facto(x-1);
}
I read in some posts which said that calling a function before it is defined is an implicit declaration. How is this statement overhere ("y = facto(6)"), an implicit declaration ?
Using GCC 4.8.1 on Ubuntu 64 bit.
y=facto(6) is an implicit declaration because you're telling the compiler "I want to call a function and pass a single int, so somewhere down the road there will be a function with a single int parameter."
If the compiler ran into the int facto(int x) first, then that's the explicit declaration.
Implicit declarations are dangerous because the compiler won't say "Hey, this doesn't match what I've already found for the function."
Declaring, is saying the compiler there is function, facto in your case, defined somewhere. You don't say how many and which type parameters this function will have, and in your case even not saying which return type it have. It only works by accident, as you used int which is default return type. If you would have your function defined as something like this
char facto(int x){...}
you would get an error. So don't use functions this way, either use prototypes, either define functions before you use them. Here some useful links :
1 2
In the following program,I use two functions prd() and display().I have declared neither of them ahead of main() before invoking them in main(),and I have defined both after main().Yet while prd() works smoothly inside main(),invoking display() shows the warning " previous implicit declaration of 'display' was here ".What is different about display() that there is a warning for it but not for the other funciton prd()?I have declared neither of them to begin with.Still there is warning due to invocation of one, but other one works fine.
#include<stdio.h>
int main()
{
int x=8,y=11;
printf("The product of %d & %d is %d",x,y,prd(x,y));
display();
return 0;
}
int prd(int x,int y)
{
return x*y;
}
void display()
{
printf("\n Good Morning");
}
PS: And I would really appreciate if you can answer this secondary question --"Is function declaration not necessary at all in C provided there is a definition for it?".I have the habit of declaring all functions of the program before the main() function, and then defining them after the main() function.Am I wrong?
When you use undeclared display() the compiler implicitly declares it as if it were returning int.
When the compiler finally sees the definition of display(), it sees that the return type is void, but it's already assumed it be int and so the definition and the implicit declaration differ, hence the error/warning.
The error occurs because C considers all non-initiated functions with a return type of int. Your display function is later defined with void return type.
Changing the return type of display() to int removes the warning.
By default, compiler assumes non-declared functions as returning int.
This is true for your prd function, but it does not match with display() as its void. This causes compiler to raise a warning.
For 2nd, its always appropriate to declare functions.
This question already has answers here:
Why do C standards allow you not to return a value from a function?
(5 answers)
Closed 4 years ago.
I'm implementing some basic data structures in C and I found out that if I omit the return type from a function and call that function the compiler doesn't generate an error. I compiled with cc file.c and didn't use -Wall (so I missed the warning) but in other programming languages this is a serious error and the program won't compile.
Per Graham Borland's request, here's a simple example:
int test()
{
printf("Hi!");
}
int main()
{
test();
}
C is an old language and at the time it was introduced, returning integers was common enough to be the default return type of a function. People later started realizing that with more complicated return types, it was best to specify int to be sure you are not forgetting the return type, but in order to maintain backwards compatibility with old code, C could not remove this default behavior. Instead most compilers issue warnings.
If the function reaches the end without a return statement an undefined value is returned except in the main function, 0 is returned. This has the same reason as above.
/* implicit declaration of printf as: int printf(int); */
/* implicit int type */
main()
{
printf("hello, world\n");
} /* implicit return 0; */
It's because in C, any variable / function is implicitly int.
This is the same reason that you can use register instead of register int, or unsigned instead of unsigned int, auto instead of auto int, and static instead of static int. I personally always explicitly qualify my variables with int, but whether you do or not is your option.
The return type of a function is optional and is considered "int" if not specified.
I haven't seen the why addressed well in any of the answers so far. In C, it's perfectly legal for a function with a non-void return type to end without a return statement/value, as long as the caller does not attempt to use the return value. For instance (slightly nontrivial example):
#include <stdio.h>
int foo(int want_result)
{
puts("hello");
if (want_result) return 42;
}
int main()
{
foo(0);
printf("%d\n", foo(1));
}
This example is somewhat contrived, but it could actually become meaningful if the return type is a huge structure that would take non-trivial time to return.
The function will not return 0 as the Matt's answer says.
In fact, printf returns a value: the number of characters printed. In your case, printf, which is the last expression in your test function, will return 3. Thus the function test will return 3.
While reading the K&R 2nd edition I noticed that the programs always began with
"main(){". I had always thought that main() had to have int or void before it. So that it would look like "int main()" or "void main()". What is just "main()" and what is the difference?
main() is the old K&R style where the int was omitted as the return type defaults to int if not specified (you should specify it). Additionally, empty parentheses is in K&R style to show it takes no arguments.. in C99 this should now be void to indicate such. Empty parentheses means that the function will accept any number of arguments of any type, which is clearly not what you want. So the final result is:
int main(void) { ... }
main() should return int.. convention says a return 0; statement at the end will help indicate to the caller that the program executed successfully - non-0 return values indicate abnormal termination.
A more direct answer to your question would be that main() { ... } works because it's not wrong. The compiler sees that no return type was declared for the main function so it defaults to int. The empty parentheses indicates to it that main takes any number of arguments of any type, which is not wrong either. However, to conform to C99 style/standard, use
int main(void) { ... }
Because this is supported in by an old version of c.
main()
is equivalent to
int main()
Syntax most of times depends on the compiler. For example, when you use visual c++ you write "void main" but when you use GCC, you should write "int main()" and then return 0 or 1 if the program finished good or bad.
I don't understand why the following code generates a warning:
int func(double a, int b, char c)
{
return 0;
}
int main()
{
int(*myPointer)() = func;
return 0;
}
I thought that in C, a function with an empty parameters list mean a function that can receive an unknown number of parameters. func4 happens to receive 3 parameters. So why is it incompatible with myPointer?
Its especially confusing because the following does compile without warning:
void boo()
{
return;
}
int main()
{
int(*pointerDude)(double) = boo;
return 0;
}
What's going on?
The difference between the two cases is explained like this: if you pass a parameter to a function that accepts none, you are just consuming some memory on the stack. If you don't pass any parameter to a function that accepts a few, the latter is going to read random data from the stack.
Update: changed to community wiki to add these corrections from Pascal Cuoq:
Casts of function pointer in both directions are legal, informative warnings from the compiler notwithstanding. Calling a function with the wrong prototype is illegal in both cases. Some ABIs mandate that the function clean up the stack, in which case passing parameters to functions that accept none corrupt the stack as surely as not passing parameters to functions that expect them.
C99 6.3.2.3 par. 8:
A pointer to a function of one type may be converted to a pointer to a
function of another type and back again; the result shall compare
equal to the original pointer. If a converted pointer is used to call
a function whose type is not compatible with the pointed-to type, the
behavior is undefined
This is the warning you get:
warning: initialization from incompatible pointer type
You are passing void which means that will require a cast. You should use the right types.
IIRC C compiler has certain assumptions which can cause very odd bugs because you're not telling it how much stack space it needs whenever that function is called. Especially since the definitions don't match this might allow someone to inadvertently read your function pointer declaration and assume no parameters and have the function return garbage. If you really want to take variable numbers of parameters use my_func(...) and varargs.
A warning is just that, a warning. Honest.
In that case, the compiler knows you have an incorrect function pointer type and it blatantly tells you that. If you try to pass a number of parameters different then 3, then it will be issued an error.
I think that the problem is related to the casting of the parameters, because char is not 32 bits. Note that if you change the char to int this works fine. It is related to automatic promotion of variables.
Compare the two:
int func();
int func(double a, int b, int c)
{
return 0;
}
and
int func();
int func(double a, int b, char c)
{
return 0;
}
gcc gives you warning for the second, but not for the first
In C an empty parameter list means that the function does not take any parameters. I believe you are confusing an empty parameter list with varargs.
Changing your first example to include the parameters will remove the warning.
int func(double a, int b, char c)
{
return 0;
}
int main()
{
int(*myPointer)(double, int, char) = func;
return 0;
}