Without header(stdio.h) file, how can the following code run? [duplicate] - c

This question already has answers here:
Why is #include <stdio.h> not required to use printf()?
(3 answers)
Closed 5 years ago.
How this following code can run without including header file for printf function?
int main(){
printf("%d",1);
return 0;}

Note: This is a hand-wavy answer that will roughly be correct. Someone else who knows the gory details (for gcc, e.g.) may enlighten both of us. Here goes:
Because in C — at least for some compilers — implicitly defined functions are fine. So it compiles it, then hands it off to the linker. It sees a reference to printf, and since the linker by default links with the C runtime library, it will resolve that symbol to the correct function.
I guess an implicit function like that will get a default signature, typically expecting to return an int. As for the arguments to the function, those can't be type checked at compile time, because the compiler doesn't know what the actual function signature is. So it will just use standard calling convention, e.g. pass arguments by registers or something like that.

Related

What happens when you call an implicitly declarated function in C? [duplicate]

This question already has answers here:
Implicit function declarations in C
(6 answers)
Closed 4 years ago.
I recently found a bug in software related to the following warning:
warning: implicit declaration of function ‘my_func’ [-Wimplicit-function-declaration]
Despite the warning, the code was compiling and (most of the time) working.
My question is, what happens when the code is running and that function is called? Is that undefined behaviour, or can I assume that the function call is a no-op?
This usually indicates that the header file that declares this subroutine was not #included. When a subroutine is used without having been declared, many C compilers generate an implicit declaration. This behavior is a common cause of errors, because the compiler may generate incorrect code if the implicit declaration does not match the actual definition.
This link contains a sample. It may be helpful to understand your concern.
An implicitly defined function is assumed to return int and to take an arbitrary number of arguments. That may or may not be true for the real function.
Depending on your platform, the arguments may be passed in an unexpected way, e. g. in registers, via the stack, etc. And if the way of passing the arguments doesn't match the expectations, things go crazy.
The default function declaration in C has parameters of int.
So, if you do not declare the function, the compiler will assume it returns int and has all parameters of int.
However, you still need to define the function or the linker will give an error.

Why don't I have "undefined reference to"? [duplicate]

This question already has answers here:
Must declare function prototype in C? [duplicate]
(10 answers)
Closed 6 years ago.
I faced a similar problem in my (big) project.
//# include <string.h> // not included
void foo(char * str, const char * delim)
{
char * tok = strtok(str, delim);
// warning ^ "assignement makes pointer from integer without a cast"
// [...]
}
The answer (just add #include <string.h> to have the prototype of strtok) solved the issue indeed.
However, due to my poor compiler/linker knowledge, I fail to understand how the process accepts a function that have not been prototyped.
I'd rather expected the error undefined reference to function 'strtok' which is typical when you forget to include the right header.
[EDIT] I understand why this question has been marked as duplicate but I do think it is different : I am aware of "good practice" regarding includes, I am just wondering about compiler's behavior. However I admit that I can found (part of) an answer to my question in this post: Are prototypes required for all functions in C89, C90 or C99? or this one: Must declare function prototype in C?
While linking your binary, unless explicitly mentioned, your binary is linked with the default C standard library (glibc, for example) anyways, where the function is defined.
So, when you miss the header file containing the declaration, you end up with the warning (in case the function prototype has a mismatchnote) but during linking time, due to the presence of the default C library, the program is successfully linked anyway.
FWIW, according to C11, support for implicit function declaration has been dropped but most compilers support the bad behavior to keep the backward compatibility for the legacy code.
NOTE:
Implicit function declaration: Earlier, (before C99, AFAIK), the standard did not mandate for a function to have the forward declaration. In case, a function would have been used without a forward declaration, it was assumed to return int and accept any number of incoming parameters.
Because gcc automatically links your code with the C library. The "undefined reference to function" error is typically issued by the linker when it couldn't resolve a symbol and that only occurs if the symbol couldn't be found in any of the libraries linked (the order of linking might also matter). But the C library is linked by default -- it's as if you linked it with -lc. So, you don't get that error.
If you tell gcc to not link the C library using -nostdlib then you'll see the error you expected:
$ gcc -nostdlib file.c
On the other hand, you should always provide prototypes for functions.
You may be interested in other similar linker options such as -nodefaultlibs, nostartfiles etc which you can find in gcc's manual.

What does a line after function declaration but outside function itself [duplicate]

This question already has answers here:
Why would you declare variables in the middle of defining a function?
(2 answers)
Closed 7 years ago.
What does it mean if something like the two lines after the main function declaration appears in C code?
int main(argc,argv)
int argc;
char *argv[];
{
// main function body
}
I've never seen anything like this before. The code works just fine, but I'm curious to know what this means. Thanks!
This is the original (read: ancient) style of declaring argument parameters in K&R C. In ANSI C standards, the form you're likely familiar with has been the standard.
See also: What are the major differences between ANSI C and K&R C?
It is just one other way of declaring the datatype of arguments of that particular function.
That's "K&R" C. It's way out of date.
Don't use it, even if your compiler supports it. Arguments passed to a function defined in that manner will have undergone argument promotion so that every argument has the same size (via the same mechanism that varargs are promoted in up-to-date C code).
Such code also does not support function declarations/prototypes. And never try to "improve" such code by creating function prototypes - you'll break the argument promotion that the function is expecting.

Ignoring the stdio.h file in a c file [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why #include <stdio.h> is *not* required to use printf()?
I am facing a problem in the below given code.
int main()
{
printf("\nHello Stack Overflow\n\n") ;
return 0 ;
}
In the above mentioned code i left including "#include ".
And if i compile and execute this piece of code, the output is printed as expected. But "#include " being the most important thing in a C program, i have ignored it and still the compilation is done without any errors but with warning.
Why is this happening?
In C, functions that are not declared are implicitly considered to return an int and to take int arguments.
This is bad practice and will bite you. For example if you want to print data not the same size of an int, like double or float.
From man gcc
-nostdlib
Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify will be
passed to the linker. The compiler may generate calls to "memcmp", "memset", "memcpy" and "memmove". These entries are usually
resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.
printf symbol is not known at compile time, but libc in linked implicite into binary... and that is how it works.

Using printf function without actually importing stdio.h and it worked?! Why is that so? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why #include <stdio.h> is not required to use printf()?
//#include <stdio.h>
//#include <conio.h>
main(){
printf("Hi");
getch();
}
As I was programming this, it shocked me that it worked without actually importing any c libraries such as stdio that contains the printf function. Why is that so? (Used Dev-C++ 4.9.9.2, saved as .c, not .cpp)
C allows you to call functions without first defining the prototypes. (C++ does not do this.) An implicit prototype for printf will be defined as follows:
int printf();
Coincidentally, the calling conventions for this implicit prototype matched the actual calling conventions for printf on your platform.
In general, you cannot count on this working, and there are a large number of cases where it won't work. I recommend enabling compiler warnings to detect implicit prototype declarations so you can fix them (by including the correct header).
Footnote: #include does not import libraries, it merely pastes files into your source code at compile time. The <stdio.h> header contains (directly or indirectly) certain prototypes, but the library has to be linked in separately. Since printf is usually in a library that is linked to programs by default, you usually don't have to do anything to use printf.
The #include preprocessor directive does not import any library; there is no such notion of import in the definition of the C language.
You just happen to call a function named printf and the standard C library (e.g. libc.so on Linux, I don't know how Windows call it) happens to be linked in by default. Since you call a function by a name known to that library, it gets linked, and is being called at runtime.
However, you should enable all warnings in you compiler, and it would warn that you call an undeclared function.

Resources