int main()
{
int main=5;
printf("%d",main);
return 0;
}
In this case there is no error and the gcc compiler prints 5. But if I write
int main()
{
int printf=5;
printf("%d",printf);
return 0;
}
the compiler shows an error..why ?
In your 1st example you "hide" the main function, replacing it with an int object.
In your 2nd example you "hide" the printf function, replacing it with an int object.
Trying to call an int is illegal.
5("foo"); /* illegal to call "function" 5 */
In your first code snippet, you declare a local variable main, which is in the local scope, so it has no effect on the global scope (where the main() function is declared)
In the second code snippet, you declare "printf" in global scope, where the printf() function lives, so you have a conflict.
In the second example, you have declared a local variable of type 'int' called 'printf'. This will take precedence over the global function of the same name. So the error is that the name 'printf' refers to an int, not a function.
In your first example, you override the global function name 'main' with a local variable called 'main'. If you had not done that, you would in fact be able to call the 'main' function from within the main function, and that would have worked. With your variable declaration, that is no longer possible as the local variable declaration takes precedence - but it's still perfectly usable in the variable form.
You shouldn't use function names as variable names, ever, for any reason.
Related
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.
After running this code:
#include <stdio.h>
int x;
int main(void)
{
printf("%d\n",x);
return 0;
}
int x=5;
I expected the output should be 0. Because of the sequence control structure of the program int x; should be executed first and then 0 is printed and finally int x=5; should be executed. But it is giving the output 5.
How is the program accesses 5 for the x in printf?
The first acts as a forward declaration, and the later acts as the actual definition.
Variable default values declared outside of functions get set before main ever runs. So what you are seeing is the correct behavior. Same goes for variables declared in other source files.
Global variables are initialised before main() runs. That means that it's entirely possible for a function to access something which appears after it in the file, as long as it's visible (i.e. forward declared).
With that said, you shouldn't really have multiple declarations for the same variable in one file. It could lead to confusion (mainly for the programmer) about what and where it's actually initialised.
EDIT: To clarify, functions/variables in global scope are not executed like a sequence of statements inside a function. The location of the function's declaration/definition has absolutely no bearing on when it gets called in relation to any other code. It only determines what parts of the surrounding scope are visible to it. In your case, this means main() does not get called in between your two int lines. It gets called by the runtime when it's finished all other initialisation.
I have a few doubts regarding the use of extern keyword with variables in C. I did go through the links related to this question. However, there are still a few things that I didn't gather very well
#include<stdio.h>
main( )
{
extern int i;
printf ( "\n%d ",i) ) ;
}
int i = 31 ;
In the above code, how does I get printed before its definition statement?
Now in the following code:
#include<stdio.h>
int x = 21 ;
main( )
{extern int i;
i=20;
printf ( "\n%d ", i ) ;
}
Isn't the statement "i=20;" a definition statement? I get an error for this. Is it because i'm trying to change the variable that is defined in some other source file? If this is the case how is the statement "int i=31;" in the top most code snippet right to use?
Also, I read, "int i;" is a definition. I don't really follow how.
In your first program, the print statement is printing the value of i based on the extern int i declaration. This is similar to calling a function based on its prototype declaration without seeing its definition. The compiler generates code to retrieve the value in the global variable named i. The symbol is resolved to the correct variable and address at link time.
In your second program, no definition for i is provided, only the extern int i declaration, and the attempt to set its value with i = 20. At link time this fails, since there is no definition, and so the attempt to resolve the reference to the global variable fails. Changing i = 20 to int i = 20 instead creates a local variable named i within the scope of the function main(), and is no longer referencing the globally declared extern int i.
When int i; is used at global scope, it is treated as a declaration and may be treated as a kind of definition. A global variable declared with an initializer, like:
int i = 20;
is always treated as a definition. Only one definition of this type is allowed, even if each is using the same initializer value. However,
int i;
is treated like a declaration. If more than one of these declarations appear, they are all treated as declarations of the same variable. At the same time, if no declaration with an initializer is present, this variable is implicitly defined with an initializer of 0, and the linker will be able to resolve references to it.
Declaration of a variable/function simply declares that the variable/function exists somewhere in the program but the memory is not allocated for them.
Coming to the definition, when we define a variable/function, apart from the role of declaration, it also allocates memory for that variable/function.
So in the 1st program, int i = 31 outside the main() defines the variable i. This variable is then merely declared as an extern variable inside the main(). Hence the program works.
In the 2nd program, without defining the variable i elsewhere, it is directly declared as an extern variable. Hence it gives an error.
In the second program you haven't defined the variable anywhere , not outside the main and instead you have defined it inside main so you are getting that error.
But in the first program you are defining the variable once and that is outside the main so you don't get that error.Program looks outside the main and find its definition.
int i; is a variable definition declaration both for AUTO variables (i.e inside main or any function ) but not for the external variables for extern variables you have to declare it like :
extern int i;
and then define outside main like this :
int i;
The idea behind extern is that you tell the compiler you're going to use a variable that was already defined outside the scope of where it is used.
It doesn't make much sense in your second case as there i is defined as a local variable.
If you were to define it as a global, like you do in the first case, it would be fine.
If I can demonstrate the use of extern with a very simple (contrived) case:
main.c:
#include <stdio.h>
extern int a; /* we tell the compiler that a will come from outside the scope of where it is used */
int main()
{
printf("%d\n", a);
return 0;
}
source.c:
int a = 3; /* we define a here */
You then compile both .c files like this:
$ gcc main.c source.c
This outputs 3.
You might also want to have a read at this article.
An 80k reputation contributor R.. told me on SO that we can't initialize global variables with the return value of a function as that's not considered a constant,and global variables must be initialized with a constant.And true to his words,I get the following error for this program as expected-- initializer element is not a constant.Here is the program:
#include<stdio.h>
int foo();
int gvar=foo(); //ERROR
int main()
{
printf("%d",gvar);
}
int foo()
{
return 8;
}
But in this context,I just don't understand why the followed altered version of the above program shows no error at all and works fine.In this second program,I am initializing the same global variable with the return value of the same function foo().Can you tell me what is the rigorous technical reason for this variation in results?Why is initializing the global variable with the return value of a function at it's declaration causing error but the same initialization with the same return value works fine when done from within a function?
#include<stdio.h>
int foo();
int gvar;
int main()
{
gvar=foo();
printf("%d",gvar);
}
int foo()
{
return 8;
}
Output 8
The reason behind it is that in order to determine a value produced by a function one needs to execute code, and that there is no code execution done in C when initializing static and global variables.
Compiler and linker work together to prepare a byte image of the global memory segment: the compiler provides the values, and the linker performs their final layout. At runtime, the image of the segment is loaded in memory as is, without further modifications. This happens before any code gets executed, so no function calls can be made.
Note that this does not mean that it is not possible for some technical reason, only that C designers decided against doing it. For example, C++ compiler generates a code segment that calls constructors of global objects, which gets executed before the control is passed to main().
The second version doesn't have an initializer for gvar. gvar is declared and defined at global scope without an initializer. It has static storage duration, so it is initialized with zero.
The assignment in main is just that: an assignment, not an initialization.
In case 1, global variable is assigned with a variable while it is declared.
But in the second case, global variable is assigned(which is already declared) with return value of foo().
Forming of data section, text section all happens during compilation.
Global variables will be in data section(bss or initialized data section), so at compile time, foo() is not invoked right? and return value of foo() is not known during compilation.
But second case, when the text section get executed, gvar is assigned with return value of foo(). It is valid.
You can maybe think of it like this: when main() starts, all global variables must already have their initializer values. And they can't, as you've been told, get those by calling functions since main() is really where execution starts, in a C program.
we could not call any function from outer of the function.Not like shell script.function only allow to called from inside of function body.
In c first execution begins from main(), compiler don't know the function calling if that stands on outer of function it may taken as prototype if arg and return types provided.
we can putting return value of function by calling from main or others function block, to the variable,the function called then (that global) variable modified.
but we can use macro in global variable as needs.
as:
#define max() 12
int glob=max();
main()
{
}
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.