Messages in this thread | | | Date | Fri, 10 Oct 2008 16:02:04 +0800 | From | Lai Jiangshan <> | Subject | Re: [PATCH] markers: remove 2 exported symbols |
| |
Mathieu Desnoyers wrote: > > See my comment in marker.h : > > * @args: variable argument list pointer. Use a pointer to overcome C's > * inability to pass this around as a pointer in a portable manner in > * the callee otherwise. > > It's an information hard to find on the web (cannot find my original > source anymore, it's mainly through forums saying that the > http://c-faq.com/varargs/handoff.html _doesn't_ work), but you'll > understand that promotion of array to pointer when passed to a function > poses problem when you try to pass this array to another function. The > following won't work on architectures where va_list is defined as an > array : > > void C(const char *fmt, va_list argp) > { > .... > } > > void B(const char *fmt, va_list argp) > { > C(fmt, argp); <--- this won't work, because we try to pass a pointer > to a function expecting an array. > } > > void A(const char *fmt, ...) > { > va_list argp; > > argp = va_start(fmt); > B(fmt, argp); > va_end(argp); > } > > The way to permit it is to pass a pointer to argp instead : > > void C(const char *fmt, va_list *argp) > { > .... > } > > void B(const char *fmt, va_list *argp) > { > C(fmt, argp); > } > > void A(const char *fmt, ...) > { > va_list argp; > > argp = va_start(fmt); > B(fmt, &argp); > va_end(argp); > } > > Mathieu >
Hi Mathieu,
I understood, and the comp.lang.c FAQ seems very authoritative. but in the kernel source I found these:
asmlinkage int vprintk(const char *fmt, va_list args) { ...... printed_len += vscnprintf(printk_buf + printed_len, sizeof(printk_buf) - printed_len, fmt, args); ..... }
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) { int i;
i=vsnprintf(buf,size,fmt,args); return (i >= size) ? (size - 1) : i; }
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
Thanks, Lai
| |