This question already has answers here:
Why does a function with no parameters (compared to the actual function definition) compile?
(11 answers)
Closed 9 years ago.
The book that i am currently reading states that when you declare a function in c that accepts no arguments, but you do not use the keyword void "the function call can pass any
arguments it wants". so i attempted this.
int number();
int main(void)
{
int x =1;
printf("%d",number(x));
}
int number()
{
return x;
}
but it did not compile??? how does this work?
This is an obsolescent feature1 from before C was standardized, decades ago.
Never use it.
In ancient C, a decade before you were born, you could declare a function with no parameters. When you called it, the compiler would promote the arguments to default types and pass them to the function. Essentially, the compiler figured out the parameter declarations from the arguments in the call.
The function should still be defined with parameters, and they should match the way the function is called.
1 “Feature” is the wrong word. It was the way things were done at the time, since better ways were not yet widely developed. In a new programming language, this characteristic would be considered a deficiency.
In support of Eric Postpischil's answer I would like to quote from the C11 standard (6.11 Future language directions)
6.11.6 Function declarators
The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.
and
6.11.7 Function definitions
The use of function definitions with separate parameter identifier and
declaration lists (not prototype-format parameter type and identifier
declarators) is an obsolescent feature.
Emphasis is mine :)
The issue here is that your function number has no knowledge of x.
That is, when you have the function number return x, it doesn't have any x in scope to return, and so this is a compile error. If, instead, you wrote:
int number() {
return 5;
}
it would compile fine.
Well, if you want pass something to it without limit , you may need a a variable argument list.Here is an example:
#include <stdio.h>
#include <stdarg.h>
int number(int , ... );
int main(void)
{
int x =1;
printf("%d",number(1,x));
}
int number(int n, ... )
{
va_list ap;
va_start(ap,n);
int x = va_arg(ap,int);
va_end(ap);
return x;
}
Or , if you just want to pass x but not use it.
#include <stdio.h>
int number();
int main(void)
{
int x =1;
printf("%d",number(x));
}
int number()
{
int x = 1;
return x;
}
It can compile and work. When you declare int number (); in C , you mean this function can be given unspecial type . however , you can't use it.
Well I edited the whole answer after finding the answer.
What you want to do is number(void) not main(void). That's what you wanted and that will print any variable as a integer. If you pass the char "F" int number(void) will return the number 70, the int form of "F". In code:
int number(void e);
void main(){
char C = 'F';
printf("%d",number(C));
};
int number(void e){
return e;
};
Note:
You must always pass an argument if you want a variable that's out of scope.
Related
I've learned function pointer is used as :
double (*ptr)(double)
ptr = my_func1;
And also, using 'typedef' could be
typedef double (*func1)(double);
func1 my_func1;
But I can't understand why this code is valid below :
int main(void){
test(a);
}
void test(int f(int))
{\
int x;\
(f==a)?(x=1):(x=2);\
printf("%d",f(x));\
}
What's that int f(int)? Is it same syntax with function pointer?
I know the type int (*)int is valid, but I've never seen the type int (int).
And Also I can't understand why the syntax in the main fuction "int f(int) = func_1" is invalid but in the 'test' function's parameter int f(int) = a is valid.
Please tell me TT Thank you.
int f(int) is a function declaration.
In C, two kinds of entities cannot be passed into functions, returned from functions or assigned: arrays and functions.
If parameters of these types are declared, they are silently turned into pointers.
A parameter int f(int) is changed to mean int (*f)(int), similarly to the way a parameter int a[3] is changed to int *a.
You might see a gratuitous warning if you declare a function one way, but define it the other; e.g.:
void test(int (*)(int));
void test(int f(int))
{
}
I've seen some version of GCC warn about this, even though it is correct; the definition and declaration are 100% compatible.
Because inside test, f is declared as a pointer, it is assignable:
f = some_func
However, in a situation where int f(int) declares a function, the identifier is not assignable:
{
int f(int); // "There exists an external f function" -- okay.
f = some_func; // Error; what? You can't assign functions!
}
Outside of function parameter declarations, functions and pointers to functions are distinguished in the usual way, as are arrays and pointers.
This question already has an answer here:
Declaring parameters outside the declarator
(1 answer)
Closed 1 year ago.
While investigating function declarations I came across a strange (to me) way of function definition:
int f(void); // declaration: takes no parameters
int g(); // declaration: takes unknown parameters
int main(void) {
f(1); // compile-time error
g(2); // undefined behavior
}
int f(void) { return 1; } // actual definition
int g(a,b,c,d) int a,b,c,d; { return 2; } // actual definition
This last line completely confused me. What does int g(a,b,c,d) int a,b,c,d; { return 2; } mean?
Such a question probably has already been asked, but I have no clue how to comprise a search query.
The definition of g uses the old K&R method of specifying argument types.
Rather then specifying the the arguments and their types inside of ( and ), only the names are specified, then the types of the arguments are specified, then the function body.
This style of declaring parameters is deprecated and should no longer be used, as it does not also qualify as a function prototype among other reasons.
We can provide an object as an initializer in another object's definition. It just copies and assigns the value of an object to another.
Is it possible to provide a function name as an initializer in another function's definition?
Where does the C standard say if it is allowed or not? I didn't find it, so I suppose it is possible.
The following two examples will result in syntax error:
#include <stdio.h>
int f(){};
int main()
{
int (g=f)();
int h() = f;
}
Thanks.
You probably want a function pointer (as a function doesn't really make sense in this context):
int (*h)() = f;
No. Function declarations can't have an initializer.
If you want to ensure type compatibility, you can use a function typedef.
typedef int f_tp(void);
f_tp f, h; //check f and h for compatibility with int (*)(void)
int f(){} //✓
//will get an error here because h was declared f_tp h == int h(void);
void h()
{
}
I am learning C and I am studying functions. So, I read that when I implement my own function I have to declare it before the main(). If I miss the declaration the compiler will get an error message.
As I was studying this example (finds if the number is a prime number),
#include <stdio.h>
void prime(); // Function prototype(declaration)
int main()
{
int num, i, flag;
num = input(); // No argument is passed to input()
for(i=2,flag=i; i<=num/2; ++i,flag=i)
{
flag = i;
if(num%i==0)
{
printf("%d is not prime\n", num);
++flag;
break;
}
}
if(flag==i)
printf("%d is prime\n", num);
return 0;
}
int input() /* Integer value is returned from input() to calling function */
{
int n;
printf("\nEnter positive enter to check: ");
scanf("%d", &n);
return n;
}
I noticed that a function prime() is declared, but in the main, a function, input(), is called and also the function input() is implemented at the bottom. Ok, I thought it was a mistake and I change the name from prime to input.
However if I delete the declaration and I don’t put any there, the program is compiled without errors and it runs smoothly. (I compile and run it on Ubuntu.)
Is it necessary to declare a void function with not arguments?
If you don't have a forward declaration of your function before the place of usage, the compiler will create implicit declaration for you - with the signature int input(). It will take the name of the function you called, it will assume that the function is returning int, and it can accept any arguments (as Bartek noted in the comment).
For this function, the implicit declaration matches the real declaration, so you don't have problems. However, you should always be careful about this, and you should always prefer forward declarations instead of implicit ones (no matter if they are same or not). So, instead of just having forward declaration of the void prime() function (assuming that you will use it somewhere), you should also have a forward declaration of int input().
To see how can you pass any number of the arguments, consider this:
#include <stdio.h>
// Takes any number of the arguments
int foo();
// Doesn't takes any arguments
int bar(void)
{
printf("Hello from bar()!\n");
return 0;
}
int main()
{
// Both works
// However, this will print junk as you're not pushing
// Any arguments on the stack - but the compiler will assume you are
foo();
// This will print 1, 2, 3
foo(1, 2, 3);
// Works
bar();
// Doesn't work
// bar(1, 2, 3);
return 0;
}
// Definition
int foo(int i, int j, int k)
{
printf("%d %d %d\n", i, j, k);
return 0;
}
So, inside the definition of the function you're describing function arguments. However, declaration of the function is telling the compiler not to do any checks on the parameters.
Not declaring a prototype and relying on default argument/return type promotion is dangerous and was a part of old C. In C99 and onward it is illegal to call a function without first providing a declaration or definition of the function.
my question is, is it necessary to declare a void function with not arguments?
Yes. For this you have to put void in the function parenthesis.
void foo(void);
Declaring a function like
void foo();
means that it can take any number of arguments.
If prime is not used, then omit the declaration.
The code won't compile as C++, because the compiler would complain that function input is used but not declared. A C compiler might issue a warning, but C is more relaxed and does an implicit declaration of input as int input() which means that you can pass any value to input and input returns an int.
It is good style to always provide a function declaration before using the function. Only if you do this the compiler can see if you are passing too few, too many or wrongly typed arguments and how to correctly handle the return value (which might be short or char instead of int).
int func(void) [5];
Why is above line not valid in c ? As anyone knows, function can be used as variable. But, I don't understand why compiler gives error .
Why I used that line is because I have tried to create 5 function-variable. To do so, I wrote like that, shown above.
Because it doesn't meet the C language valid syntax?
May be you should specify what are you trying to do with that sentence in order to get the answer you might be looking for.
This is not legal C syntax, period.
It is invalid in C++ too because functions cannot be put in arrays (you are trying to declare an array of five functions). However, the following works both in C and C++:
int (*func[5])(); // C++ version
int (*func[5])(void); // C version
and declares an array of five function pointers.
If you instead want a function which returns an array, in C you do
int *func(void);
and in C++ you do
int* func();
or
int (&func())[5];
which returns a reference to an array of five integers.
From the C standard (n1256):
6.7.5.3 Function declarators (including prototypes)
Constraints
1 A function declarator shall not specify a return type that is a function type or an array
type.
Functions cannot return array types or other function types. Functions can return pointers to those types, though:
int (*func(void))[5];
The syntax is a little weird looking, but it breaks down as follows:
func -- func
func(void) -- is a function taking no parameters
*func(void) -- returning a pointer
(*func(void))[5] -- to a 5-element array
int (*func(void))[5] -- of int
This isn't as useful as it looks: if you try to return a pointer to a local array, such as
int (*func(void))[5]
{
int arr[5] = {0,1,2,3,4};
return &arr;
}
the array no longer exists when the function returns; the pointer value you get back won't point to anything meaningful anymore.
If you're trying to create an array of functions, you have a similar problem; you cannot have an array of function types (6.7.5.2, paragraph 1, which includes the sentence "The element type shall not be an incomplete or function type"), although you can have an array of pointers to functions:
int (*func[5])(void);
This breaks down as
func -- func
func[5] -- is a 5-element array
*func[5] -- of pointers
(*func[5])(void) -- to functions taking no parameters
int (*func[5])(void) -- and returning int
Example:
int f0(void) { return 0; }
int f1(void) { return 1; }
int f2(void) { return 2; }
int f3(void) { return 3; }
int f4(void) { return 4; }
int main(void)
{
int (*func[5])(void) = {f0, f1, f2, f3, f4};
int i;
for (i = 0; i < 5; i++)
printf("f%d = %d\n", i, (*func[i])()); // or just func[i]()
return 0;
}
It is trying to declare a function that returns an array. This is not allowed - and it's nothing to do with syntax, it's a semantic rule, as demonstrated by the following (which has exactly the same problem, but is obviously syntactically fine):
typedef int FiveInts[5];
FiveInts func(void);
This is part of the "arrays are special" type rules in C. Function return values are not lvalues, and the only context in which a non-lvalue array could be used is as the subject of the sizeof operator. This makes functions returning array types completely useless.
try :
int *func(void);