function1()
{
statement1;
statement2;
function2()
{
statement3;
statement3;
}
}
why does control not enter function2, even though return type of both the functions are same
If you want to enter function2 you have to call it. The fact that you put it inside another function doesn't mean it's going to be executed, but yet declared and defined. You have to explicitly call it
function1()
{
statement1;
statement2;
function2()
{
statement3;
statement3;
}
function2();
}
And indeed Std C doesn't allow this. But it still depends on your compiler, so if you're doing this on some purpose, check with your compiler otherwise just pull the function2 declaration out of the function1's block
This is not legal C as defined by the standard. Does it even compile?
Update: Assuming GCC, CoolStraw's answer is correct.
The answer to the original question is as CoolStraw said that it isn't enough to define a nested function, you have to explicitly call it at the point you want it executed. It must be decalred before that. It has nothing to do with whether it has the same type as the containing function.
As Mat said, defining a function inside a function is not allowed by the C standard. It is a gcc extension also supported by IBM's XLC compiler.
The result type of a function has defaulted to int since the original K&R C circa 1970, and is part of all C standards so far. This is not pseudocode or a gcc extra. It's generally discouraged now because it hides mistakes; for example, if you forget "#include " and use a string function returning a pointer, it will default to returning an int. If those types are the same size, you'll get away with it, but in 64 bit mode with 32 bit ints, discarding the upper half of a pointer and replacing it with the sign extension of the lower half is a nasty bug.
Many compilers can give some kind of message warning that you've omitted the type of a function, and many will also warn that you're calling a non-void function without using the result. Both are legal, both may be exactly what you intended, but both may be errors. And most compilers can also warn about non-standard compliant extensions like gcc's nested functions. If you care about portability, enable warnings like those.
Related
What is meant by the term "implicit declaration of a function"? A call to a standard library function without including the appropriate header file produces a warning as in the case of:
int main(){
printf("How is this not an error?");
return 0;
}
Shouldn't using a function without declaring it be an error? Please explain in detail. I searched this site and found similar questions, but could not find a definitive answer. Most answers said something about including the header file to get rid of the warning, but I want to know how this is not an error.
It should be considered an error. But C is an ancient language, so it's only a warning.
Compiling with -Werror (GCC) fixes this problem.
When C doesn't find a declaration, it assumes this implicit declaration: int f();, which means the function can receive whatever you give it, and returns an integer. If this happens to be close enough (and in case of printf, it is), then things can work. In some cases (e.g., the function actually returns a pointer, and pointers are larger than ints), it may cause real trouble.
Note that this was fixed in newer C standards (C99 and C11). In these standards, this is an error. However, GCC doesn't implement these standards by default, so you still get the warning.
Implicit declarations are not valid in C.
C99 removed this feature (present in C89).
GCC chooses to only issue a warning by default with -std=c99, but a compiler has the right to refuse to translate such a program.
To complete the picture, since -Werror might considered too "invasive",
for GCC (and LLVM), a more precise solution is to transform just this warning in an error, using the option:
-Werror=implicit-function-declaration
See How can I make this GCC warning an error?.
Regarding general use of -Werror: Of course, having warningless code is recommendable, but in some stage of development it might slow down the prototyping.
Because of historical reasons going back to the very first version of C, it passes whatever type the argument is. So it could be an int or a double or a char*. Without a prototype, the compiler will pass whatever size the argument is and the function being called had better use the correct argument type to receive it.
For more details, look up K&R C.
An implicitly declared function is one that has neither a prototype nor a definition, but is called somewhere in the code. Because of that, the compiler cannot verify that this is the intended usage of the function (whether the count and the type of the arguments match). Resolving the references to it is done after compilation, at link-time (as with all other global symbols), so technically it is not a problem to skip the prototype.
It is assumed that the programmer knows what he is doing and this is the premise under which the formal contract of providing a prototype is omitted.
Nasty bugs can happen if calling the function with arguments of a wrong type or count. The most likely manifestation of this is a corruption of the stack.
Nowadays this feature might seem as an obscure oddity, but in the old days it was a way to reduce the number of header files included, hence faster compilation.
C is a very low-level language, so it permits you to create almost any legal object (.o) file that you can conceive of. You should think of C as basically dressed-up assembly language.
In particular, C does not require functions to be declared before they are used. If you call a function without declaring it, the use of the function becomes its (implicit) declaration. In a simple test I just ran, this is only a warning in the case of built-in library functions like printf (at least in GCC), but for random functions, it will compile just fine.
Of course, when you try to link, and it can't find foo, then you will get an error.
In the case of library functions like printf, some compilers contain built-in declarations for them so they can do some basic type checking, so when the implicit declaration (from the use) doesn't match the built-in declaration, you'll get a warning.
What will happen if I don't include the header files when running a c program? I know that I get warnings, but the programs runs perfectly.
I know that the header files contain function declarations. Therefore when I don't include them, how does the compiler figure it out? Does it check all the header files?
I know that I get warnings, but the programs runs perfectly.
That is an unfortunate legacy of pre-ANSI C: the language did not require function prototypes, so the standard C allows it to this day (usually, a warning can be produced to find functions called without a prototype).
When you call a function with no prototype, C compiler makes assumptions about the function being called:
Function's return type is assumed to be int
All parameters are assumed to be declared (i.e. no ... vararg stuff)
All parameters are assumed to be whatever you pass after default promotions, and so on.
If the function being called with no prototype fits these assumptions, your program will run correctly; otherwise, it's undefined behavior.
Before the 1989 ANSI C standard, there was no way to declare a function and indicate the types of its parameters. You just had to be very careful to make each call consistent with the called function, with no warning from the compiler if you got it wrong (like passing an int to sqrt()). In the absence of a visible declaration, any function you call was assumed to return int; this was the "implicit int" rule. A lot of standard functions do return int, so you could often get away with omitting a #include.
The 1989 ANSI C standard (which is also, essentially, the 1990 ISO C standard) introduced prototypes, but didn't make them mandatory (and they still aren't). So if you call
int c = getchar();
it would actually work, because getchar() returns an int.
The 1999 ISO C standard dropped the implicit int rule, and made it illegal (actually a constraint violation) to call a function with no visible declaration. So if you call a standard function without the required #include, a C99-conforming compiler must issue a diagnostic (which can be just a warning). Non-prototype function declarations (ones that don't specify the types of the arguments) are still legal, but they're considered obsolescent.
(The 2011 ISO C standard didn't change much in this particular area.)
But there's still plenty of code out there that was written for C90 compilers, and most modern compilers still support the older standard.
So if you call a standard function without the required #include, what will probably happen is that (a) the compiler will warn you about the missing declaration, and (b) it will assume that the function returns int and takes whatever number and type(s) of arguments you actually passed it (also accounting for type promotion, such as short to int and float to double). If the call is correct, and if you compiler is lenient, then your code will probably work -- but you'll have one more thing to worry about if it fails, perhaps for some unrelated reason.
Variadic functions like printf are another matter. Even in C89/C90, calling printf with no visible prototype had undefined behavior. A compiler can use an entirely different calling convention for variadic functions, so printf("hello") and puts("hello") might generate quite different code. But again, for compatibility with old code, most compilers use a compatible calling convention, so for example the first "hello world" program in K&R1 will probably still compile and run.
You can also write your own declarations for standard functions; the compiler doesn't care whether it sees a declaration in a standard header or in your own source file. But there's no point in doing so. Declarations have changed subtly from one version of the standard to the next, and the headers that came with your implementation should be the correct ones.
So what will actually happen if you call a standard function without the corresponding #include?
In a typical working environment, it doesn't matter, because with any luck your program won't survive code review.
In principle, any compiler that conforms to C99 or later may reject your program with a fatal error message. (gcc will behave this way with -std=c99 -pedantic-errors) In practice, most compilers will merely print a warning. The call will probably work if the function returns int (or if you ignore the result) and if you get all the argument types correct. If the call is incorrect, the compiler may not be able to print good diagnostics. If the function doesn't return int, the compiler will probably assume that it does, and you'll get garbage results, or even crash your program.
So you can study this answer of mine, follow up by reading the various versions of the C standard, find out exactly which edition of the standard your compiler conforms to, and determine the circumstances in which you can safely omit a #include header -- with the risk that you'll mess something up next time you modify your program.
Or you can pay attention to your compiler's warnings (Which you've enabled with whatever command-line options are available), read the documentation for each function you call, add the required #includes at the top of each source file, and not have to worry about any of this stuff.
First of all: just include them.
If you don't the compiler will use the default prototype for undeclared functions, which is:
int functionName(int argument);
So it will compile, and link if the functions are available. But you will have problems at runtime.
There are a lot of things you can't do if you leave out headers:
(I'm hoping to get some more from the comments since my memory is failing on this ...)
You can't use any of the macros defined in the headers. This can be significant.
The compiler can't check that you are calling functions properly since the headers define their parameters for it.
For compatibility with old program C compilers can compile code calling functions which have not been declared, assuming the parameters and return value is of type int. What can happen? See for example this question: Troubling converting string to long long in C I think it's a great illustration of the problems you can run into if you don't include necessary headers and so don't declare functions you use. What happened to the guy was he tried to use atoll without including stdlib.h where atoll is declared:
char s[30] = { "115" };
long long t = atoll(s);
printf("Value is: %lld\n", t);
Surprisingly, this printed 0, not 115, as expected! Why? Because the compiler didn't see the declaration of atoll and assumed it's return value is an int, and so picked only part of the value left on stack by the function, in other words the return value got truncated.
That's why of the reasons it is recommended to compile your code with -Wall (all warnings on).
What will happen if I don't include the header files when running a c program? I know that I get warnings, but the programs runs perfectly.
I know that the header files contain function declarations. Therefore when I don't include them, how does the compiler figure it out? Does it check all the header files?
I know that I get warnings, but the programs runs perfectly.
That is an unfortunate legacy of pre-ANSI C: the language did not require function prototypes, so the standard C allows it to this day (usually, a warning can be produced to find functions called without a prototype).
When you call a function with no prototype, C compiler makes assumptions about the function being called:
Function's return type is assumed to be int
All parameters are assumed to be declared (i.e. no ... vararg stuff)
All parameters are assumed to be whatever you pass after default promotions, and so on.
If the function being called with no prototype fits these assumptions, your program will run correctly; otherwise, it's undefined behavior.
Before the 1989 ANSI C standard, there was no way to declare a function and indicate the types of its parameters. You just had to be very careful to make each call consistent with the called function, with no warning from the compiler if you got it wrong (like passing an int to sqrt()). In the absence of a visible declaration, any function you call was assumed to return int; this was the "implicit int" rule. A lot of standard functions do return int, so you could often get away with omitting a #include.
The 1989 ANSI C standard (which is also, essentially, the 1990 ISO C standard) introduced prototypes, but didn't make them mandatory (and they still aren't). So if you call
int c = getchar();
it would actually work, because getchar() returns an int.
The 1999 ISO C standard dropped the implicit int rule, and made it illegal (actually a constraint violation) to call a function with no visible declaration. So if you call a standard function without the required #include, a C99-conforming compiler must issue a diagnostic (which can be just a warning). Non-prototype function declarations (ones that don't specify the types of the arguments) are still legal, but they're considered obsolescent.
(The 2011 ISO C standard didn't change much in this particular area.)
But there's still plenty of code out there that was written for C90 compilers, and most modern compilers still support the older standard.
So if you call a standard function without the required #include, what will probably happen is that (a) the compiler will warn you about the missing declaration, and (b) it will assume that the function returns int and takes whatever number and type(s) of arguments you actually passed it (also accounting for type promotion, such as short to int and float to double). If the call is correct, and if you compiler is lenient, then your code will probably work -- but you'll have one more thing to worry about if it fails, perhaps for some unrelated reason.
Variadic functions like printf are another matter. Even in C89/C90, calling printf with no visible prototype had undefined behavior. A compiler can use an entirely different calling convention for variadic functions, so printf("hello") and puts("hello") might generate quite different code. But again, for compatibility with old code, most compilers use a compatible calling convention, so for example the first "hello world" program in K&R1 will probably still compile and run.
You can also write your own declarations for standard functions; the compiler doesn't care whether it sees a declaration in a standard header or in your own source file. But there's no point in doing so. Declarations have changed subtly from one version of the standard to the next, and the headers that came with your implementation should be the correct ones.
So what will actually happen if you call a standard function without the corresponding #include?
In a typical working environment, it doesn't matter, because with any luck your program won't survive code review.
In principle, any compiler that conforms to C99 or later may reject your program with a fatal error message. (gcc will behave this way with -std=c99 -pedantic-errors) In practice, most compilers will merely print a warning. The call will probably work if the function returns int (or if you ignore the result) and if you get all the argument types correct. If the call is incorrect, the compiler may not be able to print good diagnostics. If the function doesn't return int, the compiler will probably assume that it does, and you'll get garbage results, or even crash your program.
So you can study this answer of mine, follow up by reading the various versions of the C standard, find out exactly which edition of the standard your compiler conforms to, and determine the circumstances in which you can safely omit a #include header -- with the risk that you'll mess something up next time you modify your program.
Or you can pay attention to your compiler's warnings (Which you've enabled with whatever command-line options are available), read the documentation for each function you call, add the required #includes at the top of each source file, and not have to worry about any of this stuff.
First of all: just include them.
If you don't the compiler will use the default prototype for undeclared functions, which is:
int functionName(int argument);
So it will compile, and link if the functions are available. But you will have problems at runtime.
There are a lot of things you can't do if you leave out headers:
(I'm hoping to get some more from the comments since my memory is failing on this ...)
You can't use any of the macros defined in the headers. This can be significant.
The compiler can't check that you are calling functions properly since the headers define their parameters for it.
For compatibility with old program C compilers can compile code calling functions which have not been declared, assuming the parameters and return value is of type int. What can happen? See for example this question: Troubling converting string to long long in C I think it's a great illustration of the problems you can run into if you don't include necessary headers and so don't declare functions you use. What happened to the guy was he tried to use atoll without including stdlib.h where atoll is declared:
char s[30] = { "115" };
long long t = atoll(s);
printf("Value is: %lld\n", t);
Surprisingly, this printed 0, not 115, as expected! Why? Because the compiler didn't see the declaration of atoll and assumed it's return value is an int, and so picked only part of the value left on stack by the function, in other words the return value got truncated.
That's why of the reasons it is recommended to compile your code with -Wall (all warnings on).
I'm dealing with some pre-ANSI C syntax. See I have the following function call in one conditional
BPNN *net;
// Some more code
double val;
// Some more code, and then,
if (evaluate_performance(net, &val, 0)) {
But then the function evaluate_performance was defined as follows (below the function which has the above-mentioned conditional):
evaluate_performance(net, err)
BPNN *net;
double *err;
{
How come evaluate_performance was defined with two parameters but called with three arguments? What does the '0' mean?
And, by the way, I'm pretty sure that it isn't calling some other evaluate_performance defined elsewhere; I've greped through all the files involved and I'm pretty sure the we are supposed to be talking about the same evaluate_performance here.
Thanks!
If you call a function that doesn't have a declared prototype (as is the case here), then the compiler assumes that it takes an arbitrary number and types of arguments and returns an int. Furthermore, char and short arguments are promoted to ints, and floats are promoted to doubles (these are called the default argument promotions).
This is considered bad practice in new C code, for obvious reasons -- if the function doesn't return int, badness could ensure, you prevent the compiler from checking that you're passing the correct number and types of parameters, and arguments might get promoted incorrectly.
C99, the latest edition of the C standard, removes this feature from the language, but in practice many compilers still allow them even when operating in C99 mode, for legacy compatibility.
As for the extra parameters, they are technically undefined behavior according to the C89 standard. But in practice, they will typically just be ignored by the runtime.
The code is incorrect, but in a way that a compiler is not required to diagnose. (A C99 compiler would complain about it.)
Old-style function definitions don't specify the number of arguments a function expects. A call to a function without a visible prototype is assumed to return int and to have the number and type(s) of arguments implied by the calls (with narrow integer types being promoted to int or unsigned int, and float being promoted to double). (C99 removed this; your code is invalid under the C99 standard.)
This applies even if the definition precedes the call (an old-style definition doesn't provide a prototype).
If such a function is called incorrectly, the behavior is undefined. In other words, it's entirely the programmer's responsibility to get the arguments right; the compiler won't diagnose errors.
This obviously isn't an ideal situation; it can lead to lots of undetected errors.
Which is exactly why ANSI added prototypes to the language.
Why are you still dealing with old-style function definitions? Can you update the code to use prototypes?
Even standard C compilers are somewhat permissive when it comes to this. Try running the following:
int foo()
{
printf("here");
}
int main()
{
foo(3,4);
return 0;
}
It will, to some's surprise, output "here". The extra arguments are just ignored. Of course, it depends on the compiler.
Overloading doesn't exist in C so having 2 declarations would not work in the same text.
That must be a quite old compiler to not err on this one or it did not find the declaration of the function yet!
Some compilers would not warn/err when calling an undefined function. That's probably what you're running into. I would suggest you look at the command line flags of the compiler to see whether there is a flag you can use to get these warnings because you may actually find quite a few similar mistakes (too many parameters is likely to work just fine, but too few will make use of "undefined" values...)
Note that it is possible to do such (add extra parameters) when using the ellipsis as in printf():
printf(const char *format, ...);
I would imagine that the function had 3 parameters at some point and the last was removed because it was unused and some parts of the code was not corrected as it ought to be. I would remove that 3rd parameter, just in case the stack goes in the wrong order and thus fails to send the correct parameters to the function.
I'm very curious to know why exactly C89 compilers will dump on you when you try to mix variable declarations and code, like this for example:
rutski#imac:~$ cat test.c
#include <stdio.h>
int
main(void)
{
printf("Hello World!\n");
int x = 7;
printf("%d!\n", x);
return 0;
}
rutski#imac:~$ gcc -std=c89 -pedantic test.c
test.c: In function ‘main’:
test.c:7: warning: ISO C90 forbids mixed declarations and code
rutski#imac:~$
Yes, you can avoid this sort of thing by staying away from -pedantic. But then your code is no longer standards compliant. And as anybody capable of answering this post probably already knows, this is not just a theoretical concern. Platforms like Microsoft's C compiler enforce this quick in the standard under any and all circumstances.
Given how ancient C is, I would imagine that this feature is due to some historical issue dating back to the extraordinary hardware limitations of the 70's, but I don't know the details. Or am I totally wrong there?
The C standard said "thou shalt not", because it was not allowed in the earlier C compilers which the C89 standard standardized. It was a radical enough step to create a language that could be used for writing an operating system and its utilities. The concept probably simply wasn't considered - no other language at the time allowed it (Pascal, Algol, PL/1, Fortran, COBOL), so C didn't need to either. And it probably makes the compiler slightly harder to handle (bigger), and the original compilers were space-constrained by the 64 KiB code and 64 KiB data space allowed in the PDP 11 series (the big machines; the littler ones only allowed 64 KiB for both code and data, AFAIK). So, extra complexity was not a good idea.
It was C++ that allowed declarations and variables to be interleaved, but C++ is not, and never has been, C. However, C99 finally caught up with C++ (it is a useful feature). Sadly, though, Microsoft never implemented C99.
It was probably never implemented that way, because it was never needed.
Suppose you want to write something like this in plain C:
int myfunction(int value)
{
if (value==0)
return 0;
int result = value * 2;
return result;
}
Then you can easily rewrite this in valid C, like this:
int myfunction(int value)
{
int result;
if (value==0)
return 0;
result = value * 2;
return result;
}
There is absolutely no performance impact by first declaring the variable, then setting its value.
However, in C++, this is not the case anymore.
In the following example, function2 will be slower than function1:
double function1(const Factory &factory)
{
if (!factory.isWorking())
return 0;
Product product(factory.makeProduct());
return product.getQuantity();
}
double function2(const Factory &factory)
{
Product product;
if (!factory.isWorking())
return 0;
product = factory.makeProduct();
return product.getQuantity();
}
In function2 the product variable needs to be constructed, even when the factory is not working.
Later, the factory makes the product and then the assignment operator needs to copy the product (from the return value of makeProduct to the product variable). In function1, product is only constructed when the factory is working, and even then, the copy constructor is called, not the normal constructor and assignment operator.
However, I would expect nowadays that a good C++ compiler would optimize this code, but in the first C++ compilers this probably wasn't the case.
A second example is the following:
double function1(const Factory &factory)
{
if (!factory.isWorking())
return 0;
Product &product = factory.getProduct();
return product.getQuantity();
}
double function2(const Factory &factory)
{
Product &product;
if (!factory.isWorking())
return 0;
product = factory.getProduct(); // Invalid. You can't assign to a reference.
return product.getQuantity();
}
In this example, function2 is simply invalid. References can only be assigned a value at declaration time, not later.
This means that in this example, the only way to write valid code is to write the declaration at the moment where the variable is really initialized. Not sooner.
Both examples show why it was really needed in C++ to allow variable declarations after other executable statements, and not in the beginning of the block like in C.
This explains why this was added to C++, and not to C (and other languages) where it isn't really needed.
It is similar to requiring functions to be declared before they are used - it allows a simple-minded compiler to operate in one pass, from top to bottom, emitting object code as it goes.
In this particular case, the compiler can go through the declarations, adding up the stack space required. When it reaches the first statement, it can output the code to adjust the stack, allocating space for the locals, immediately before the start of the function code proper.
It is much easier to write a compiler for language which requires all variables to be declared at the start of function. Some languages even require variables to be declared in specific clause outside of function code (Pascal and Smalltalk come to mind).
The reason is it's easier to map this variables to stack (or registers if your compiler is smart enough) if they are known and don't change.
Any other statements (esp. function calls) may modify stack/registers, making variable mapping more complex.