Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is wrong with this recursive va_arg code?
    primarykey
    data
    text
    <p>I'm trying to make a generic function taking a variable argument list. A part of the design is that some of these functions call each other. Unfortunately it doesn't seem to work. As you can see if you run the simple code below, the call to command() always fails, but the direct call to marshal_size() succeeds in decoding the two strings "FIRST_STR_ARG" and "SECOND_STR_ARG" according to the format string "FORMAT_STRING".</p> <p>What is wrong in my reasoning?</p> <p>The sample code compiles equally well with "g++ main.cpp" or "gcc main.c". </p> <p>Thanks,<br> &nbsp;&nbsp;jules</p> <pre><code>#include &lt;stdarg.h&gt; #include &lt;stdio.h&gt; #include &lt;inttypes.h&gt; #include &lt;string.h&gt; #include &lt;stdlib.h&gt; #define MARSHAL_FORMAT "%s%s" #define FIRST_STR_ARG "THIS_IS_ARG_ONE" #define SECOND_STR_ARG "THIS_IS_ARG_TWO" #define d(msg__, ...) do { printf("%s@%d: "msg__"\n", __FILE__, __LINE__, ## __VA_ARGS__); } while (0) static uint32_t marshal_size(const char *format, ...) { uint32_t retv = 0; uint8_t ub; uint16_t uw; uint32_t ul; char *s; va_list ap; if (!format || !strlen(format)) return 0; d("format = %s \n", format); va_start(ap, format); for (; '\0' != *format; format++) { d("*format = %c \n", *format); if ('%' == *format) { format++; if ('u' == *format) format++; } else { d("FORMAT ERROR\n"); continue; } d("*format = %c \n", *format); switch (*format) { case 's': s = va_arg(ap, char*); d("va_arg = %s\n", (s ? s : "NULL")); if (s) retv += strlen(s) + 1; break; case 'l': ul = va_arg(ap, uint32_t); retv += sizeof(uint32_t); break; case 'w': uw = (uint16_t)va_arg(ap, int); retv += sizeof(uint16_t); break; case 'b': ub = (uint8_t)va_arg(ap, int); retv += sizeof(uint8_t); break; default: goto exit; } continue; exit: break; } va_end(ap); return retv; } static uint32_t command(const char * const format, ...) { uint32_t retv; va_list ap; va_start(ap, format); retv = marshal_size(format, ap); va_end(ap); return retv; } int main(int argc, char *argv) { uint32_t size; size = command(MARSHAL_FORMAT, FIRST_STR_ARG, SECOND_STR_ARG); d("size = %d", size); size = marshal_size(MARSHAL_FORMAT, FIRST_STR_ARG, SECOND_STR_ARG); d("size = %d", size); return EXIT_SUCCESS; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload