How to use printf() without any libraries in C? - c

I am programming a Teensy micro-controller as a part of a C course and am trying to work out the value of one of my integer variables. I have an integer variable called Contrast, which is initialised to the value of a constant defined as a hexadecimal number at the beginning of the .c file:
#define LCD_DEFAULT_CONTRAST 0x3F
int Contrast = LCD_DEFAULT_CONTRAST;
I am trying to investigate how this Contrast value is stored and displayed, if it shows up as 63 or 0x3F, and if they are interchangeable. I tried to use:
printf("%d", Contrast);
to print out the Contrast value to the terminal and I got the error implicit declaration of function 'printf'. I thought printf() was part of the built-in C library, so I am confused why this is not working.
Can anyone please tell me how I print the value of this variable to the screen?

The implicit declaration error just means your compiler proper doesn't have a declaration for printf. Unless you're also getting a linker error, the linker (linking usually follows compilation, unless you pass -c to disable it) is probably slapping the standard lib right on, in which case you can simply solve your warning by including stdio.h or less preferably by declaring int printf(char const*, ...);.
If you trully don't have the standard lib, you'll need to convert the integer to a string manually with something like:
int n = 42;
char buf[20];
char *end = buf+(sizeof(buf)-1), *p = end;
*p--=0;
if(n==0) *p=='0';
else{
while(n){
printf("%d\n", n%10);
*p--=n%10+'0';
n/=10;
}
p++;
}
and then pass it to your system's raw IO routine for which you'll need to have set up the system-entering assembly.
If you don't have a system, it'd be even more technical, and you probably wouldn't be asking this question.

printf() is declared in standard library header <stdio.h>.
You have to #include <stdio.h> to use printf(). It is a library call, much like all other library calls in C..

Related

C: convert argv[1] to double

I need to pass a double to my program, but the following does not work:
int main(int argc, char *argv[]) {
double ddd;
ddd=atof(argv[1]);
printf("%f\n", ddd);
return 0;
}
If I run my program as ./myprog 3.14 it still prints 0.000000.
Can somebody please help?
My guess is you forgot to include #include <stdlib.h>. If this is the case, gcc will issue the following warning:
warning: implicit declaration of function 'atof' [-Wimplicit-function-declaration]
And give the exact output you provided: 0.000000.
As remyabel indicated, you probably neglected to #include <stdlib.h>. The reason this matters is that, without having a declaration of atof(), the C standard mandates that the return value is assumed to be int. In this case, it's not int, which means that the actual behavior you observe (getting a return value of 0) is technically unspecified.
To be clear, without the double-returning declaration, the line ddd=atof(argv[1]) is treated as a call to an int-returning function, whose result is then cast to a double. It is likely the case that the calling conventions on the particular system you're on specify that ints and doubles get returned in different registers, so the 0 is likely just to be whatever happened to be in that particular register, while the double return value is languishing, unobserved.
In C you don't require to declare a function before you use it (in contrast with C++), and if that happens (no prototype), compiler makes some assumptions about that function. One of those assumptions is that it returns int. There's no error, atof() works, but it works incorrectly. It typically get whatever value happens to be in the register where int is supposed to be returned (it is 0 in your case, but it can be something else).
P.S. atof() and atoi() hide input errors (which you can always see by adding option -Wall to your gcc compiler call: gcc -Wall test.c), so most people prefer to use strtol() and strtod() instead.

Segmentation fault while accessing the return address from a C function in 64 bit machine

I have code in C (linux(x86_64)) some like this:
typedef struct
{
char k[32];
int v;
}ABC;
ABC states[6] = {0};
ABC* get_abc()
{
return &states[5];
}
while in main():
int main()
{
ABC *p = get_abc();
.
.
.
printf("%d\n", p->v);
}
I am getting segmentation fault at printf statement while accessing p->v. I tried to debug it from gdb and it says "can not access the memory". One important thing here is that when I compile this code, gcc throws me a warning on ABC *p = get_abc(); that I am trying to convert pointer from integer. My question here is that I am returning address of structure from get_abc() then why compiler gives me such warning? why compiler considers it as integer? I think I am getting segmentation fault due to this warning as an integer can not hold memory address in x86_64.
Any help would be appreciated.
Define the get_abc prototype before main function. If function prototype is not available before that function call means, compiler will treat that function by default as passing int arguments and returning int. Here get_abc actually returning 8 byte address, but that value has been suppressed to 4 bytes and it is stored in ABC *p variable which leads the crash.
ABC* get_abc();
int main()
{
ABC *p = get_abc();
}
Note : This crash will not occur in 32 bit machine where size of int and size of address is 4 bytes, because suppression will not happen. But that warning will be there.
You haven't shown us all your code, but I can guess with some confidence that the get_abc() and main() functions are defined in separate source files, and that there's no visible declaration of get_abc() visible from the call in main().
You should create a header file that contains a declaration of get_abc():
ABC *get_abc();
and #include that header both in the file that defines get_abc() and in the one that defines main(). (You'll also need header guards.) You'll need to move the definition of the type ABC to that header.
Or, as a quick-and-dirty workaround, you can add an explicit declaration before your definition of main() -- but that's a rather brittle solution, since it depends on you to get the declaration exactly right.
In the absence of a visible declaration, and undeclared function is assumed to return int. The compiler sees your call to get_abc(), generates code to call it as if it returned an int, and implicitly converts that int value to a pointer. Hilarity ensues.
Note: There actually is no implicit conversion from int to pointer types, apart from the special case of a null pointer constant, but many compilers implement such an implicit conversion for historical reasons. Also, the "implicit int" rule was dropped in the 1999 version of the standard, but again, many compilers still implement it for historical reasons. Your compiler should have options to enable better warnings. If you're using gcc, try gcc -pedantic -std=c99 -Wall -Wextra.

when I return the address of a static var in a function, the address is not correct

ProtobufCAllocator *kvs_pb_allocator()
{
static ProtobufCAllocator allocator;
//do something here
return &allocator; //print the address, it is 0x2aaaaafc12c0
}
In another program call this function (from a different file):
ProtobufCAllocator *alloctor = kvs_pb_allocator();
//print the address, it is 0xffffffffaafc12c0
Why did this problem happen? The other daemon program I wrote works fine. Just in this situation it prints the wrong value.
You're on a 64-bit machine and didn't use a type-safe mechanism for printing the address in the second location. The value got chopped to 32-bits, then sign-extended to 64 bits.
0x00002aaa_aafc12c0
0xffffffff_aafc12c0
where the underscore indicates the 32-bit boundary in the middle of the values. The trouble is more likely in the way you're printing the value than in the value itself.
You can verify this by printing the address more carefully. You could use:
printf("Address: %p\n", (void *)alloctor);
since this is C.
I assume (perhaps without justification) that you do have a header that declares the function kvs_pb_allocator() and that the header is used both in the file where you define the function and in the file where you call it. If not, then get into the discipline of ensuring that all functions are declared (or defined if they are static functions) before they are used. All external functions should be declared in a header. All code that references a given function should use the single header that declares that function. This is necessary in C99 and C2011; you should impose the discipline upon yourself if you're stuck with a C89 compiler.
If you use GCC, you can use:
gcc -std=c99 -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition
to get the warnings. Your code would get a warning for an old-style definition because you should define:
ProtobufCAllocator *kvs_pb_allocator(void)
{
...
}
Did you declare the function in the file you called it from. If not, the compiler will assume that it returns an int, your code will extend the int to a pointer.

Is declaring an header file essential?

Is declaring an header file essential? This code:
main()
{
int i=100;
printf("%d\n",i);
}
seems to work, the output that I get is 100. Even without using stdio.h header file. How is this possible?
You don't have to include the header file. Its purpose is to let the compiler know all the information about stdio, but it's by no means necessary if your compiler is smart (or lazy).
You should include it because it's a good habit to get into - if you don't, then the compiler has no real way to know if you're breaking the rules, such as with:
int main (void) {
puts (7); // should be a string.
return 0;
}
which compiles without issue but rightly dumps core when running. Changing it to:
#include <stdio.h>
int main (void) {
puts (7);
return 0;
}
will result in the compiler warning you with something like:
qq.c:3: warning: passing argument 1 of ‘puts’ makes pointer
from integer without a cast
A decent compiler may warn you about this, such as gcc knowing about what printf is supposed to look like, even without the header:
qq.c:7: warning: incompatible implicit declaration of
built-in function ‘printf’
How is this possible? In short: three pieces of luck.
This is possible because some compilers will make assumptions about undeclared functions. Specifically, parameters are assumed to be int, and the return type also int. Since an int is often the same size as a char* (depending on the architecture), you can get away with passing ints and strings, as the correct size parameter will get pushed onto the stack.
In your example, since printf was not declared, it was assumed to take two int parameters, and you passed a char* and an int which is "compatible" in terms of the invocation. So the compiler shrugged and generated some code that should have been about right. (It really should have warned you about an undeclared function.)
So the first piece of luck was that the compiler's assumption was compatible with the real function.
Then at the linker stage, because printf is part of the C Standard Library, the compiler/linker will automatically include this in the link stage. Since the printf symbol was indeed in the C stdlib, the linker resolved the symbol and all was well. The linking was the second piece of luck, as a function anywhere other than the standard library will need its library linked in also.
Finally, at runtime we see your third piece of luck. The compiler made a blind assumption, the symbol happened to be linked in by default. But - at runtime you could have easily passed data in such a way as to crash your app. Fortunately the parameters matched up, and the right thing ended up occurring. This will certainly not always be the case, and I daresay the above would have probably failed on a 64-bit system.
So - to answer the original question, it really is essential to include header files, because if it works, it is only through blind luck!
As paxidiablo said its not necessary but this is only true for functions and variables but if your header file provides some types or macros (#define) that you use then you must include the header file to use them because they are needed before linking happens i.e during pre-processing or compiling
This is possible because when C compiler sees an undeclared function call (printf() in your case) it assumes that it has
int printf(...)
signature and tries to call it casting all the arguments to int type. Since "int" and "void *" types often have same size it works most of the time. But it is not wise to rely on such behavior.
C supprots three types of function argument forms:
Known fixed arguments: this is when you declare function with arguments: foo(int x, double y).
Unknown fixed arguments: this is when you declare it with empty parentheses: foo() (not be confused with foo(void): it is the first form without arguments), or not declare it at all.
Variable arguments: this is when you declare it with ellipsis: foo(int x, ...).
When you see standard function working then function definition (which is in form 1 or 3) is compatible with form 2 (using same calling convention). Many old std. library functions are so (as desugned to be), because they are there form early versions of C, where was no function declarations and they all was in form 2. Other function may be unintentionally be compatible with form 2, if they have arguments as declared in argument promotion rules for this form. But some may not be so.
But form 2 need programmer to pass arguments of same types everywhere, because compiler not able to check arguments with prototype and have to determine calling convention osing actual passed arguments.
For example, on MC68000 machine first two integer arguments for fixed arg functions (for both forms 1 and 2) will be passed in registers D0 and D1, first two pointers in A0 and A1, all others passed through stack. So, for example function fwrite(const void * ptr, size_t size, size_t count, FILE * stream); will get arguments as: ptr in A0, size in D0, count in D1 and stream in A1 (and return a result in D0). When you included stdio.h it will be so whatever you pass to it.
When you do not include stdio.h another thing happens. As you call fwrite with fwrite(data, sizeof(*data), 5, myfile) compiler looks on argruments and see that function is called as fwrite(*, int, int, *). So what it do? It pass first pointer in A0, first int in D0, second int in D1 and second pointer in A1, so it what we need.
But when you try to call it as fwrite(data, sizeof(*data), 5.0, myfile), with count is of double type, compiler will try to pass count through stack, as it is not integer. But function require is in D1. Shit happens: D1 contain some garbage and not count, so further behaviour is unpredictable. But than you use prototype defined in stdio.h all will be ok: compiler automatically convert this argument to int and pass it as needed. It is not abstract example as double in arument may be just result of computation involving floating point numbers and you may just miss this assuming result is int.
Another example is variable argument function (form 3) like printf(char *fmt, ...). For it calling convention require last named argument (fmt here) to be passed through stack regardess of its type. So, then you call printf("%d", 10) it will put pointer to "%d" and number 10 on stack and call function as need.
But when you do not include stdio.h comiler will not know that printf is vararg function and will suppose that printf("%d", 10) is calling to function with fixed arguments of type pointer and int. So MC68000 will place pointer to A0 and int to D0 instead of stack and result is again unpredictable.
There may be luck that arguments was previously on stack and occasionally read there and you get correct result... this time... but another time is will fail. Another luck is that compiler takes care if not declared function may be vararg (and somehow makes call compatible with both forms). Or all arguments in all forms are just passed through stack on your machine, so fixed, unknown and vararg forms are just called identically.
So: do not do this even you feel lucky and it works. Unknown fixed argument form is there just for compatibility with old code and is strictly discouraged to use.
Also note: C++ will not allow this at all, as it require function to be declared with known arguments.

C programming language, array, pointer

int main()
{
int j=97;
char arr[4]="Abc";
printf(arr,j);
getch();
return 0;
}
this code gives me a stack overflow error why?
But if instead of printf(arr,j) we use printf(arr) then it prints Abc.
please tell me how printf works , means 1st argument is const char* type so how arr is
treated by compiler.
sorry! above code is right it doesn't give any error,I write this by mistake. but below code give stack overflow error.
#include <stdio.h>
int main()
{
int i, a[i];
getch();
return 0;
}
since variable i take any garbage value so that will be the size of the array
so why this code give this error when i use DEV C++ and if I use TURBO C++ 3.0 then
error:constant expression required displayed. if size of array can't be variable then when
we take size of array through user input.no error is displayed. but why in this case.
please tell me how printf works
First of all, pass only non-user supplied or validated strings to the first argument of printf()!
printf() accepts a variable number of arguments after the required const char* argument (because printf() is what's called a variadic function). The first const char* argument is where you pass a format string so that printf() knows how to display the rest of your arguments.
If the arr character array contains user-inputted values, then it may cause a segfault if the string happens to contain those formatting placeholders, so the format string should always be a hard-coded constant (or validated) string. Your code sample is simple enough to see that it's really a constant, but it's still good practice to get used to printf("%s", arr) to display strings instead of passing them directly to the first argument (unless you absolutely have to of course).
That being said, you use the formatting placeholders (those that start with %) to format the output. If you want to display:
Abc 97
Then your call to printf() should be:
printf("%s %d", arr, j);
The %s tells printf() that the second argument should be interpreted as a pointer to a null-terminated string. The %d tells printf() that the third argument should be interpreted as a signed decimal.
this code gives me a stack overflow error why?
See AndreyT's answer.
I see that now the OP changed the description of the behavior to something totally different, so my explanation no longer applies to his code. Nevertheless, the points I made about variadic functions still stand.
This code results in stack invalidation (or something similar) because you failed to declare function printf. printf is a so called variadic function, it takes variable number of arguments. In C language it has [almost] always been mandatory to declare variadic functions before calling them. The practical reason for this requirement is that variadic functions might (and often will) require some special approach for argument passing. It is often called a calling convention. If you forget to declare a variadic function before calling it, a pre-C99 compiler will assume that it is an ordinary non-variadic function and call it as an ordinary function. I.e. it will use a wrong calling convention, which in turn will lead to stack invalidation. This all depends on the implementation: some might even appear to "work" fine, some will crash. But in any case you absolutely have to declare variadic functions before calling them.
In this case you should include <stdio.h> before calling printf. Header file <stdio.h> is a standard header that contains the declaration of printf. You forgot to do it; hence the error (most likely). There's no way to be 100% sure, since it depends on the implementation.
Otherwise, your code is valid. The code is weird, since you are passing j to printf without supplying a format specifier for it, but it is not an error - printf simply ignores extra variadic arguments. Your code should print Abc in any case. Add #include <stdio.h> at the beginning of your code, and it should work fine, assuming it does what you wanted it to do.
Again, this code
#include <stdio.h>
int main()
{
int j=97;
char arr[4]="Abc";
printf(arr,j);
return 0;
}
is a strange, but perfectly valid C program with a perfectly defined output (adding \n at the end of the output would be a good idea though).
In your line int i, a[i]; in the corrected sample of broken code, a is a variable-length array of i elements, but i is uninitialized. Thus your program has undefined behavior.
You see strings in C language are treated as char* and printf function can print a string directly. For printing strings using this function you should use such code:
printf("%s", arr);
%s tells the function that the first variable will be char*.
If you want to print both arr and j you should define the format first:
printf("%s%d", arr, j);
%d tells the function that the second variable will be int
I suspect the printf() issue is a red herring, since with a null-terminated "Abc" will ignore other arguments.
Have you debugged your program? If not can you be sure the fault isn't in getch()?
I cannot duplicate your issue but then I commented out the getch() for simplicity.
BTW, why did you not use fgetc() or getchar()? Are you intending to use curses in a larger program?
===== Added after your edit =====
Okay, not a red herring, just a mistake by the OP.
C++ does allow allocating an array with the size specified by a variable; you've essentially done this with random (garbage) size and overflowed the stack, as you deduced. When you compile with C++ you are typically no longer compiling C and the rules change (depending on the particular compiler).
That said, I don't understand your question - you need to be a lot more clear with "when we take size of array through user input" ...

Resources