Reputation: 45
Program:
#ifndef PRINTF_H
#define PRINTF_H
#include "my_put_char.h"
int my_printf(char *str, ...);
#endif
This is my Header file for my function.
#include <stdio.h>
#include "my_put_char.h"
void my_put_char(char c)
{
fwrite(&c, sizeof(char), 1, stdout);
}
This is my putchar implementation(my_put_char.c).
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "printf.h"
int my_printf(char *str, ...)
{
if(str == NULL)
return 0;
int i;
char a;
va_list print;
va_start(print,str);
for(i = 0; str[i] ; i++)
{
if(str[i] == '%')
{
i++;
switch(str[i])
{
case 'c':
a = va_arg(print, char);
my_put_char(a);
break;
}
}
}
va_end(print);
return 0;
}
At last, this is a part of my printf implementation.
I'm testing with %c
to display a character.
When I do my_print("%c", 'd');
from main.c
it compiles and displays d
.
But when I do my_print("%c", "hi");
, it still compiles and displays a number.
Question:
After(or before) writing a = va_arg(print, char);
Is there a way to check whether my input is a different data type?
I'm trying to display an error if my input is a different data type.
I'm on this subject for 2 days and couldn't find any answer. Thank you so much for your time!
Upvotes: 3
Views: 924
Reputation: 1
when I do
my_print("%c", "hi");
, it still compiles and displays a number
You've got some undefined behavior, so be scared. Your my_printf
would call va_arg
with an argument of the bad type (expected char
promoted to int
, got char*
).
To explain what is happening you should dive into implementation details (look into the assembler code, e.g. with gcc -Wall -fverbose-asm -O -S
; study your processor, its instruction set architecture, its application binary interface and calling conventions). You don't want to do that, it could take years and is not reproducible.
Read absolutely Lattner's blog on UB, right now!
Then download C11 specification n1570....
You could also, with gcc
, use some function attributes. Don't forget to compile with all warnings and debug info (gcc -Wall -Wextra -g
)
after writing
a = va_arg(print, char);
Is there a way to check whether my input is a different data type?
No, not really and not always. But the format
function attribute could help. And you could also spend months customizing GCC with your own plugin or some GCC MELT extension (that is not worth your time). Be aware of the Halting Problem and Rice's Theorem (each makes static source code program analysis so challenging). Look also into source analyzing tools like Frama-C.
I'm implementing printf function
BTW studying the source code of existing free software implementations of the C standard library (such as GNU glibc and musl-libc) could be inspirational; they are based upon syscalls(2).
Upvotes: 3