Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6358475
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T23:22:55+00:00 2026-05-24T23:22:55+00:00

Consider the following test case: #define _GNU_SOURCE #include <stdio.h> #include <stdarg.h> void test(char **outa,

  • 0

Consider the following test case:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdarg.h>

void test(char **outa, char **outb, const char* fstra, const char* fstrb, ...) {
    va_list ap;

    va_start(ap, fstrb);
    vasprintf(&outa, fstra, ap);
    vasprintf(&outb, fstrb, ap);
    va_end(ap);
}

int main(void) {
    char *a, *b;
    test(&a, &b, "%s", " %s\n", "foo", "bar");
    /* ... */
}

The intent here is that the test() function takes two format strings and a list of parameters for both of them. The first format string is supposed to ‘eat’ as many arguments it needs, and the remaining ones are supposed to be used for the second format string.

So, the expected result here would be foo & bar and that’s what I get with glibc. But AFAICS the machine running codepad (guess some *BSD it is), gives foo & foo and my guess is that it uses va_copy() on the argument list.

I guess I’m hitting an undefined (and ugly) behavior here; so the question is: is there a way to achieve double-format-string printf() without reimplementing it from scratch? And is there a nice way to check that behavior using autoconf without using AC_RUN_IFELSE()?

I guess some quick method of scanning format-string for the number of arguments to be consumed could work here as well (+va_copy()).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T23:22:56+00:00Added an answer on May 24, 2026 at 11:22 pm

    As the other answer already states, passing ap to a v*() function leaves ap in an undetermined state. So, the solution is to not depend on this state. I suggest an alternative workaround.

    First, initialize ap as normal. Then determine the length of the first formatted string using vsnprintf(NULL, 0, fstra, ap). Concatenate the format strings, reinitialize ap, and split the output using the predetermined length of the first formatted string.

    It should look something like the following:

    void test(const char* fstra, const char* fstrb, ...) {
      char *format, *buf;
      char *a, *b;
      int a_len, buf_len;
      va_list ap;
    
      va_start(ap, fstrb);
      a_len = vsnprintf(NULL, 0, fstra, ap);
      va_end(ap);
    
      asprintf(&format, "%s%s", fstra, fstrb);
    
      va_start(ap, fstrb);
      buf_len = vasprintf(&buf, format, ap);
      va_end(ap);
      free(format);
    
      a = malloc(a_len + 1);
      memcpy(a, buf, a_len);
      a[a_len] = '\0';
    
      b = malloc(buf_len - a_len + 1);
      memcpy(b, buf + a_len, buf_len - a_len);
      b[buf_len - a_len] = '\0';
      free(buf);
    }
    

    As also discussed in the other answer, this approach does not separate positional printf-style placeholders ("%1$s. I repeat, %1$s."). So the documentation for the interface should clearly state that both format strings share the same positional placeholder namespace—and that if one of the format strings uses positional placeholders then both must.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Consider the following test case: public class Main { static int a = 0;
Consider the following test case: $start = new DateTime(2011-02-25); $end = new DateTime(2011-03-25); $interval
Consider the following test: [Test] public void Create_ServiceWithDynamicDependency_Created() { // arrange IWindsorContainer container =
Consider the following code, public class StartUp { public StartUp(String[] test){} public static void
Consider following class class test { public: test(int x){ cout<< test \n; } };
Consider the following ruby code test.rb: begin puts thisFunctionDoesNotExist x = 1+1 rescue Exception
Consider following example : public class SomeBusinessLayerService : DataService<MyEntityContainer> { [WebInvoke] void DoSomething(string someParam)
Consider the following code: void Handler(object o, EventArgs e) { // I swear o
Consider the following test snippet: // act AutoResetEvent workDoneEvent = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(delegate {
This has been driving me nuts for hours now. Consider the following test script

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.