1

In C, under the stdarg.h library, variable arguments can be accepted by a function or procedure and usually the argument list is preceded by a count of the number of arguments to follow. Is it possible to validate the user's count of the arguments?

I suspect that it must be possible, because printf() is a varargs function and if the programmer has a mismatch between the number of tags in the format string, and the number of arguments supplied, then a runtime error occurs. So, it seems that printf has some way of detecting the number of arguments supplied.

Tyler Durden
  • 11,156
  • 9
  • 64
  • 126
  • Do you mean placeholders vs. argument count mismatches? – tadman Sep 28 '20 at 22:58
  • 5
    The C standard does not provide any facility for this. In general, `printf` implementations cannot and do not provide run-time errors for this, although using incorrect arguments can generate run-time errors such as attempts to access unmapped memory. C compilers commonly provide compile-time errors for this, when they can see the format string. – Eric Postpischil Sep 28 '20 at 22:58
  • Does this answer your question? [How to count the number of arguments passed to a function that accepts a variable number of arguments?](https://stackoverflow.com/questions/4421681/how-to-count-the-number-of-arguments-passed-to-a-function-that-accepts-a-variabl) – Carcigenicate Sep 28 '20 at 22:59
  • If you believe you have an example of `printf` providing a run-time error for this, then edit the question to provide a [mre] and specify the specific compiler and C library version you are using. – Eric Postpischil Sep 28 '20 at 22:59
  • In gcc this is done with `format` attribute: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes – Piotr Praszmo Sep 28 '20 at 23:06
  • @PiotrPraszmo: That does not do what OP requested. – Eric Postpischil Sep 28 '20 at 23:07
  • Are you sure it's a runtime error? Compilers will do compile-time checks that printf arguments match the format string, and produce warnings. – Barmar Sep 28 '20 at 23:09
  • @Barmar compiler runtime. So it is some kind of runtime as compiler is running during the compilation – 0___________ Sep 28 '20 at 23:21
  • 2
    `printf` typically does *not* validate the argument count at runtime. Instead, it assumes the right number of arguments were passed; if too few were, then it typically uses instead whatever garbage happens to be in that register or memory location. This *might* cause a runtime error, or garbage output with no error, or demons flying out your nose, or it might have no effect at all. It's simply undefined behavior. – Nate Eldredge Sep 28 '20 at 23:31
  • @NateEldredge `printf` **never** validates the paramets runtime as it is not possible. – 0___________ Sep 28 '20 at 23:36
  • 1
    @P__J__: There are architectures where it is possible. For that matter, an ABI could be designed for x86 that would support it. – Eric Postpischil Sep 28 '20 at 23:37
  • It isn't a runtime argument. When gcc compiles `printf("Hello World %s %s","asd");` it returns this warning "warning: format ‘%s’ expects a matching ‘char*’ argument [-Wformat=]" – Jerry Jeremiah Sep 28 '20 at 23:40
  • @EricPostpischil C does not have such a mechanisms using stdarg. This king of validation will have very significant performance impact. Because of that we have UBs. If you do not want UBs but validation use language which is designed this way. – 0___________ Sep 28 '20 at 23:40
  • @JerryJeremiah I think you do not understand the difference between the runtime and compile time. – 0___________ Sep 28 '20 at 23:42
  • @P__J__ I don't think an ABI that passed a count as a hidden parameter would have a very significant performance impact. The compiler juast has to pass an extra parameter under the covers exactly like the this pointer is done. – Jerry Jeremiah Sep 28 '20 at 23:43
  • @P__J__ I do understand the difference. I was responding to the comment that said "Are you sure it's a runtime error?" And if I didn't understand the difference then there wouldn't have been any point in responding. – Jerry Jeremiah Sep 28 '20 at 23:44
  • 2
    @P__J__ And in response to your "printf never validates the paramets runtime as it is not possible." I think you are wrong. Some architectures can validate the parameters so "never" is incorrect. What you meant to say is that the standard doesn't require it. – Jerry Jeremiah Sep 28 '20 at 23:46
  • @P__J__: “C does not have such a mechanisms using stdarg“ and “it is not possible” are different statements. C has no mechanism for displaying GUI windows, yet is is possible in C. C has no mechanism for communicating via Internet, yet it is possible in C. – Eric Postpischil Sep 29 '20 at 00:03

2 Answers2

2

The C standard does not provide any facility for this. In general, printf implementations cannot and do not provide run-time errors for this1, although using incorrect arguments can generate run-time errors such as attempts to access unmapped memory. C compilers commonly provide compile-time errors for this, when they can see the format string.

Footnote

1 It is not technically impossible for a C implementation to provide this as a feature, but most C implementations do not have the capability, largely because they conform to ABIs that do not support it.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

It is not possible in C language.

printf does not count the parameters. During the compilation compiler analyses the format string and compares it with the parameters. It is not done runtime only compile time.

It is quite easy to spot when the format specifier is not known compile time:

#include <stdio.h>
void foo(const char *str)
{
    printf(str, 34, 57.0, (void *)5655);
}

void bar(void)
{
    printf("%s, %d, %c", 34, 57.0, (void *)5655);
}

https://godbolt.org/z/ans7Kh

0___________
  • 60,014
  • 4
  • 34
  • 74