I found this question on an online exam. This is the code:
#include <stdio.h>
int main(void) {
int demo();
demo();
(*demo)();
return 0;
}
int demo(){
printf("Morning");
}
I saw the answer after the test. This is the answer:
MorningMorning
I read the explanation, but can't understand why this is the answer.
I mean, shouldn't the line int demo(); cause any "problem"?
Any explanation is helpful. Thanks.
It is not a problem because that int demo(); is not a function definition, it is just an external declaration, saying (declaring) that a function of such name exists.
In C you cannot define a nested function:
int main(void) {
int demo() {} //Error: nested function!!!
}
But you can declare a function just fine. It is actually equivalent to:
#include <stdio.h>
int demo(); //function declaration, not definition
int main(void) {
demo();
(*demo)();
return 0;
}
int demo(){
printf("Morning");
}
except that in your code the external forward demo() declaration is only visible inside main.
You can declare a function inside another function. This is allowed. The only thing is it is visible only inside the function in which it is declared.
Other answers didn't explain the
(*demo)();
part. Here's a partial explanation:
demo (without parentheses) is the function pointer. So you can first dereference it to get a function then call it with parentheses (wrapping the dereferenced object into parentheses else it means that you want to dereference the return value of the function)
So it's strictly equivalent to
demo();
(the notation is useful when the function pointer is stored in a variable, here it's just more cryptic than necessary)
int main(void) { int demo(); /*...*/ }; int demo(){ /*...*/ }
is equivalent to
int main(void) { extern int demo(); /*...*/ }; int demo(){ /*...*/ }
It declares the demo function with external linkage, inside the main function.
The demo identifier will be valid till the end of the scope, but demo will be a
normal, external function.
Unfortunately, you cannot do this for functions that are static, because
the standard (http://port70.net/~nsz/c/c11/n1570.html#note30) makes things like
int main(void) { static int demo(); } static int demo(){ /*...*/ }
illegal.
As to why (*demo)(); works and is in this context equivalent to demo(); or (&demo)(); or (*&demo)();:
After you declare demo with int demo();, demo is a function designator (which is not the same as a function pointer, not unlike an array designator is not the same as a pointer the the array's first element). Like arrays, though, function designators almost always decay to function pointers (see 6.3.2.1p4) and this type of decay happens in function calls too. Essentially demo(); decays demo to a pointer and then calls
the function pointer. Applying * to such a pointer yields again the function designator which again decays to a pointer to make the call.
Admittedly, all this stuff is very weird and esoteric and I can't even think of a situation where the distinction is useful. IMHO, it's probably best to stick to demo(); or (demo)() (if you want to supress macro expansion) and never use (*demo)() (at least not on functions -- on function pointers it is at least somewhat informative) and especially not (&demo)() as it serves little purpose other than to confuse the reader.
Related
I just started learning C, and I came across this in one of the example given, I know this is a function prototype, but the concept I am yet to wrap my head around is the fact that does
void function(char *);
mean when I finally declare the function, it is going take an argument char pointer argument like so
void function(char *arg){}
?
Just to answer the question you gave:
What does “void fatal(char *);” mean?
This is the prototype/declaration of the function fatal.fatal is a function, which takes a pointer to char as one and only argument.
void is the return type of the function, which in this case mean that the function does not return a value to its caller or if it does, the value returned is interpreted as invalid by the caller.
The prototype/declaration of the function fatal() is important for the compiler. In this way, primarily the compiler will get "known", how the function is later used in the following program but secondary also checks if there are any inconsistencies between the definition, declaration and the use of the function.
In C, You may omit a specific identifier for the pointer to char in the declaration of the function, but not in the definition. This a circumstance where C is different as C++; In C++ it is permissible to omit the identifier also in the definition. You can look at the respective phrases in the standards in this answer.
So in the definition of fatal in C you have to provide an identifier for the char pointer:
// Definition of function fatal().
void fatal(char *a)
{
printf("The string of (a) is: %s\n",a);
}
but you can omit this one in the declaration:
void fatal(char *);
Note: The identifier between the provided arguments, when calling the function and the parameters specified in the declaration of the function may vary, like:
// Declaration (Protoype) of function fatal().
void fatal(char* a); // parameter a (pointer to char);
int main()
{
char b[] = "Hello"; // Declaration and Initialization of array b.
printf("Let´s use the function fatal to print what the string in b is
contained of!\n");
fatal(b); // when given as argument to a function, b
// is a pointer to the first element of the char
// array of b.
}
// Definition of function fatal().
void fatal(char* a)
{
printf("The string of (a) is: %s\n",a);
}
See more about the difference between parameters and arguments here: What's the difference between an argument and a parameter?
In the more far view, there is also an important difference between "pass by value" and "pass by reference". A pointer argument/parameter is always a pass by reference. What these two especially are and how they distinct is best explained here: What's the difference between passing by reference vs. passing by value?
In this context and the context of scope visibility, it is also important to know if you have f.e. an identifier x which refers to an object in the function fatal, the same identifier of x can be used in the caller, and vice versa, to refer to a total different object in each scope. - Means, you can have the same identifier (name) for different objects in different scopes but each identifier can only used once in its scope.
Here void function(char *); is a function prototype which is simply the declaration of a function that specifies function's name, parameters and return type. It doesn't contain function body.
It gives information to the compiler that the function may later be used in the program.
It is not needed if the user-defined function is defined before the main() function.
does
[...] mean when I finally declare the function, it is going take an argument char pointer argument [...]
?
Yes, it does.
The important thing with the declaration of the function are the parameters' types. The parameters' names are not needed within the declaration
void function(char *);
but only within the function's definition
void function(char *arg)
{
}
.
It just informs the compiler what type parameters functions takes and what is the return type of it.
int main()
{
double x = foo(1,2);
}
void foo(double x)
{
printf("%f", x);
}
in this compiler does not know what parameters of the function foo are and how to pass them properly. Return type is also unknown. The compiler will assume they are int - which is not the truth in this case
https://godbolt.org/z/J8juc4
If there is no function prototype, a function is implicitly declared by its first appearance in an expression.
In C, if a function return anything else than int it is a good habit to declare the function inside the caller function like 1st example of code.
But you are always constrained by the compiler to write the prototype, the reason is that he does not know who the function is because it is declared underneath the main() function.
The question is: These two are equivalent? Will either writing the prototype or declaring explicitly the function inside the main() return the wanted result? How can it return a bad value if you are constrained always to use one of this two ways?
if the function is declared in the same script as the caller function is (here main())
prototype
declare explicitly function in main().
if the function is declared in another file
prototype
declare explicitly function in main()
E.g:
int main()
{
double doSomething(int a);
printf("%d", doSomething(2) );
}
double doSomething(int a)
{
return a * 2.0;
}
vs
double doSomething(int a);
int main()
{
printf("%d", doSomething(2) );
}
double doSomething(int a)
{
return a * 2.0;
}
This thread is almost what i needed but it did not answer all my questions.
C language - calling functions without function prototype
These two declarations are equivalent until in the first case the function doSomething will be required in some other function except main.
In this code snippet
int main()
{
double doSomething(int a);
//..
there is a function prototype of the function doSomething.
From the C Standard
A function prototype is a declaration of a function that declares the
types of its parameters
That is before the function definition that is also its declaration the name of the function will be visible only in the block scope of main.
Consider the following program
#include <stdio.h>
void g( void )
{
f( 20 );
}
int main(void)
{
void f( int );
f( 10 );
return 0;
}
void f( int x )
{
printf( "x = %d\n", x );
}
The compiler will issue an error for this statement
f( 20 );
because the name f is not yet declared.
But this statement
f( 10 );
is correct because the name inside the block scope of main is already declared.
To make it more clear take into account that functions always has a linkage opposite to variables declared in a block scope without a storage class specifier.
So this declaration in main
double doSomething(int a);
is equivalent to the declaration
extern double doSomething(int a);
And the linker will find the function definition even if the function initially is declared in a block scope.
In modern C, you should always declare a function before using it. (That includes defining a function before using it, because a definition is a declaration.) Implicit declaration of functions to return int is a behavior of very old verions of C. It should not be used, compilers should at least warn about it, and you should set your compiler to make it an error, not a warning.
Functions are usually declared outside of other functions. There is nothing explicitly wrong about declaring a function inside another function, but we rarely do it because we generally want functions to be visible throughout a translation unit, not just in one specific place. (A translation unit is one source file together with all the files it includes via #include directives.) The names of functions obey the same scope rules as object names: If it appears outside of any function, it has file scope. If it appears inside a block (a list of statements inside braces, { … }, which includes function bodies), it has block scope and is only visible in that block.
Whether a function is declared at file scope or block scope will not affect how it behaves.
main is not special in this regard. You are likely asking about main because you are early in your programming education, and you mostly call functions just from main. However, functions may be called from other functions, and the rules about scope and name visibility are not particular to main. If a function is declared at file scope, its name is visible throughout the rest of the translation unit. If a function is declared at block scope, whether inside main or another function, its name is visible throughout the rest of that block.
If a function is defined to return double but you use it without declaring it, and your compiler allows that, then you can expect your program to work incorrectly. The compiler will not automatically convert double to int. The function type is important to tell the compiler what the function returns because the compiler expects certain bits to be in certain places when the function returns, and it writes instructions relying on that.
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.
This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed 9 years ago.
In a book, I came across the following question.
The problem which I am facing is, what is a function pointer? How does it work and what is the syntax for it's declaration.
Point the error in given code.
main()
{
int (*p)()=fun;
(*p)();
}
fun()
{
printf("Hi..");
}
my first question is, What does following code snipet signifies?
int (*p)()=fun;
(*p)();
and second obvious question what is the error in the given code..??
refer to ionela.voinescu's answer for solution.. it is same as that written in solution manual..thnx
int (*p)() = fun declares a pointer to a function that returns int, then assigns the address of the function fun to that pointer. (*p)() calls whatever function p is pointing to.
Problems with your code:
fun and main should have a return type. Your compiler might not demand it and assume they return ints, but you should give them one nonetheless.
You need to declare fun above main, or use a prototype
Also, (*p)() is unnecessary; you can just use p().
As a side note, because function pointer syntax is relatively ugly, it's fairly common to see typedefs such as
typedef int(*IntFunc)();
which would allow you to declare and use p like so:
IntFunc p = fun;
p();
The correct code is the following:
#include <stdio.h>
int fun();
int main(){
int (*p)()=fun;
(*p)();
return 0;
}
int fun(){
printf("Hi..");
return 0;
}
1.
int fun();
You have to declare your function before using it in main; Otherwise main wont recognize it.
2.
int (*p)() : Declaration of a variable p which is a pointer to a function that returns int and has no arguments(or undefined number of arguments, depending on the standard).
3.
int fun();
.........
int (*p)()=fun;
In order for this to work fun must also return int. Meaning when assigning a value to a variable this must have a type which corresponds with the declaration of the variable. When assigning a value to a pointer to a function that returns int and has no arguments the function assigned to it must also return int and have no arguments (or undefined number of arguments, depending on the standard).
4.
(*p)();
You call the function p which now points to fun.
fun is name of the the function itself.
int (*p)()
is the definition of the function pointer like 'int a' is the definition of an integer.
int * is the pointer itself, () means it is a pointer to a function.
(*p)();
This is the execution of the function of the function pointer p, i.e. p is assigned to the function fun, which is executed by calling the content of the pointer p, thus (*p)();
So, this is code from a student of my friend…
#include <stdio.h>
int main(){
int hours;
int take_one_number(void);{
scanf("%d",&hours);
}
int minutes;
int take_one_number(void);{
scanf("%d",&minutes);
}
int seconds;
int take_one_number(void);{
scanf("%d",&seconds);
}
int all;
printf("%d",all=hours*3600+minutes*60+seconds);
return all;
}
Well, it… compiles… and… uhm, works… as requested by the teacher…
My question: if I understand correctly, take_one_number here is a definition of a variable to store a function pointer. Why does neither GCC nor LLVM complain about a duplicated identifier in these definitions?
The function take_one_number is declared 3 times, but never defined. In each case, the ; after the (void) ends the declaration. The scanf statement is then just a regular statement inside of main(), surrounded by a meaningless scope { }
In the above code ,
int take_one_number (void);
is not a function pointer , it is function prototype or declaration , a function can be declared more than once , but must be defined only once.
int take_one_number(void);
It's a function declaration whose return type is int. It's not a definition of a variable. And the scoping you did for variables has little meaning here as no variable declaration is happening in it.
int take_one_number(void); is a function prototype to tell the compiler that there is a function implemented somewhere with this name and property. Compiler does not complain because you are neither defining new function nor using that function.
You should also note that the blocks that follow after this prototype are not part of the take_one_number as they are separated with semi-colon. Making the blocks as independent scope blocks. To make things more clearer there would be compilation error if there were no semi-colon between the function prototype and the code block next to it.