Adam said:
Adam said:
I have a simple printf-like function:
int print(const char *format, ...)
{
� char buffer[1024];
� va_list argptr;
� int i;
� va_start(argptr, format);
� i = vsnprintf(buffer, sizeof(buffer), format, argptr);
� va_end(argptr);
� buffer[sizeof(buffer)-1] = '\0';
� printf("%s\n",buffer); /* this bit just for the sake of testing */
If I call the function using something like:
char message[50];
strcpy(message, "hi there");
print("%s",message);
everything works, but if I do:
print(message);
it doesn't (program crashes with an abort).
I don't see a problem myself. �I took your function and added a main function:
#include <stdarg.h>
#include <stdio.h>
/* your function */
int main(void) {
� print("%s\n", "Hello world!");
� print("Goodbye world!\n");
� return 0;
}
and it compiles and runs without problems on three different systems.
Actually, the bit I was wondering about was passing a (char *) to the
print function, rather than a literal string. I did find this page:
http://www.eskimo.com/~scs/cclass/int/sx11c.html
...which seems to suggest (in the first paragraph) this might be
wrong.
In C, the type of a string literal is char*; when used in this
contexts, (and most other contexts) "message" decays to a char* too.
Therefore, whatever issue might arise with a string literal will also
arise with "message".
The first paragraph that you refer to on that web page talks about the
integer promotions, which only apply to integer types like 'char'.
Pointer types like 'char *' remain unaffected by the integer
promotions.
Well, the compiler is GCC. Trouble is, I can't replicate it in a
simple example (and a complex example would take me well out of
comp.lang.c territory).
Start with your complicated example, and start simplifying it by
removing things. Test after each removal. When a removal causes the
problem to disappear, put it back in and remove something else. If you
do this systematically, you will either produce a minimum-size program
that demonstrates the problem which you can post to this group, no
matter how long it is; or you'll realize what the problem is. In my
experience, it's usually the second possibility that actually comes
up.
This isn't your problem, but what's the purpose of [buffer[sizeof(buffer)-1] = '\0']?
Hmm, well when I originally wrote a function like this I wasn't sure
about the rules for whether it would get terminated or not and it
seemed it didn't if the incoming string was truncated. However, a
similar test now seems to reveal it does work, as you say.
Performing a test is not a goodway to figure this out. The test will
tell you what your compiler does; it won't tell you whether this a
special case, or something you can rely on. Reading and understanding
the documentation of the vsnprintf() function is the best way. The
standard's description of vsnprintf() cross-references snprintf(). The
description of snprintf() says "a null character is written at the end
of the characters actually written into the array." The documentation
that comes with your compiler should say roughly the same thing.