Skip to main content
formatting
Source Link
Konrad Rudolph
  • 549.3k
  • 142
  • 967
  • 1.3k

Let's start with some background: per the documentation, you need to call va_start before invoking va_arg on any va_list:

  • va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg "va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg". (Source)

  • Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end "Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end". (Source)

I would imagine not calling va_start is undefined behaviorundefined behavior, but I couldn't find a specific callout to state as such.

In your question, the function int max(int n, va_list vals) is not "really" variadic, since it accepts a fixed number of arguments: 2. These are int n and va_list vals.

Per the documentation "The declaration of a variadic function uses an ellipsis as the last parameter, e.g. The declaration of a variadic function uses an ellipsis as the last parameter, e.g. int printf(const char* format, ...);"

So, it depends on how you implement it, but I would recommend documenting the int max(int n, va_list vals) to accept a va_list that is already initialized with a va_start call. The rationale being that it is not technically "variadic" and does not really "own" the va_list. It just accepts it as an input from some other source.

The actual variadic function int max_first(int n, ...) should be the one creating the va_list and priming it with the call to va_start before passing it anywhere.

Although, as far as I can tell, there's no way to check if a va_list already has va_start called on it or not. And there's no guarantee that it will be called before being passed to your function, so I suspect this would have to be enforced by documentation and convention.

Let's start with some background: per the documentation, you need to call va_start before invoking va_arg on any va_list:

  • va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg. (Source)

  • Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end. (Source)

I would imagine not calling va_start is undefined behavior, but I couldn't find a specific callout to state as such.

In your question, the function int max(int n, va_list vals) is not "really" variadic, since it accepts a fixed number of arguments: 2. These are int n and va_list vals.

Per the documentation The declaration of a variadic function uses an ellipsis as the last parameter, e.g. int printf(const char* format, ...);

So, it depends on how you implement it, but I would recommend documenting the int max(int n, va_list vals) to accept a va_list that is already initialized with a va_start call. The rationale being that it is not technically "variadic" and does not really "own" the va_list. It just accepts it as an input from some other source.

The actual variadic function int max_first(int n, ...) should be the one creating the va_list and priming it with the call to va_start before passing it anywhere.

Although, as far as I can tell, there's no way to check if a va_list already has va_start called on it or not. And there's no guarantee that it will be called before being passed to your function, so I suspect this would have to be enforced by documentation and convention.

Let's start with some background: per the documentation, you need to call va_start before invoking va_arg on any va_list:

  • "va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg". (Source)

  • "Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end". (Source)

I would imagine not calling va_start is undefined behavior, but I couldn't find a specific callout to state as such.

In your question, the function int max(int n, va_list vals) is not "really" variadic, since it accepts a fixed number of arguments: 2. These are int n and va_list vals.

Per the documentation "The declaration of a variadic function uses an ellipsis as the last parameter, e.g. int printf(const char* format, ...);"

So, it depends on how you implement it, but I would recommend documenting the int max(int n, va_list vals) to accept a va_list that is already initialized with a va_start call. The rationale being that it is not technically "variadic" and does not really "own" the va_list. It just accepts it as an input from some other source.

The actual variadic function int max_first(int n, ...) should be the one creating the va_list and priming it with the call to va_start before passing it anywhere.

Although, as far as I can tell, there's no way to check if a va_list already has va_start called on it or not. And there's no guarantee that it will be called before being passed to your function, so I suspect this would have to be enforced by documentation and convention.

Post Undeleted by MrHappyAsthma
added 481 characters in body
Source Link
MrHappyAsthma
  • 6.5k
  • 10
  • 53
  • 81

YesLet's start with some background: per the documentation, you shouldneed to call va_start first.before invoking va_arg on any va_list:

  • va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg. (Source)

  • Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end. (Source)

Per the instructions in the documentation:I would imagine not calling va_start should be invoked with an instance is undefined tobehavior, but I couldn't find a specific callout to state as such.

In your question, the function int amax(int validn, va_list object ap before any callsvals) is not "really" variadic, since it accepts a fixed number of arguments: 2. These are int ton and va_list va_argvals. (Source)

This is also confirmed onPer the va_arg documentation:documentation Prior to calling va_arg,The apdeclaration mustof bea initializedvariadic byfunction auses callan toellipsis eitheras va_startthe orlast va_copyparameter, withe.g. noint interveningprintf(const callchar* toformat, va_end...);. (Source)

So, it depends on how you implement it, but I would imagine not callingrecommend documenting the va_startint max(int n, va_list vals) isto accept a undefined behaviorva_list, but I couldn't find that is already initialized with a specific callout to state as suchva_start call. I would imagine it'sThe rationale being that it is not safe to rely ontechnically "variadic" and does not really "own" the va_list. It just accepts it working, even ifas an input from some other source.

The actual variadic function int max_first(int n, ...) should be the one creating the va_list and priming it happenedwith the call to run correctly in one demova_start before passing it anywhere.

Here'sAlthough, as far as I can tell, there's no way to check if a good example from GNU:va_list already has va_start called on it or not. And there's no guarantee that it will be called before being passed to your function, so I suspect this would have to be enforced by documentation and convention.

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

int add_em_up (int count,...)
{
  va_list ap;
  int i, sum;

  va_start (ap, count);         /* Initialize the argument list. */

  sum = 0;
  for (i = 0; i < count; i++)
    sum += va_arg (ap, int);    /* Get the next argument value. */

  va_end (ap);                  /* Clean up. */
  return sum;
}

int main (void)
{
  /* This call prints 16. */
  printf ("%d\n", add_em_up (3, 5, 5, 6));

  /* This call prints 55. */
  printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  return 0;
}

Yes, you should call va_start first.

Per the instructions in the documentation: va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg. (Source)

This is also confirmed on the va_arg documentation: Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end. (Source)

I would imagine not calling va_start is undefined behavior, but I couldn't find a specific callout to state as such. I would imagine it's not safe to rely on it working, even if it happened to run correctly in one demo.

Here's a good example from GNU:

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

int add_em_up (int count,...)
{
  va_list ap;
  int i, sum;

  va_start (ap, count);         /* Initialize the argument list. */

  sum = 0;
  for (i = 0; i < count; i++)
    sum += va_arg (ap, int);    /* Get the next argument value. */

  va_end (ap);                  /* Clean up. */
  return sum;
}

int main (void)
{
  /* This call prints 16. */
  printf ("%d\n", add_em_up (3, 5, 5, 6));

  /* This call prints 55. */
  printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  return 0;
}

Let's start with some background: per the documentation, you need to call va_start before invoking va_arg on any va_list:

  • va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg. (Source)

  • Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end. (Source)

I would imagine not calling va_start is undefined behavior, but I couldn't find a specific callout to state as such.

In your question, the function int max(int n, va_list vals) is not "really" variadic, since it accepts a fixed number of arguments: 2. These are int n and va_list vals.

Per the documentation The declaration of a variadic function uses an ellipsis as the last parameter, e.g. int printf(const char* format, ...);

So, it depends on how you implement it, but I would recommend documenting the int max(int n, va_list vals) to accept a va_list that is already initialized with a va_start call. The rationale being that it is not technically "variadic" and does not really "own" the va_list. It just accepts it as an input from some other source.

The actual variadic function int max_first(int n, ...) should be the one creating the va_list and priming it with the call to va_start before passing it anywhere.

Although, as far as I can tell, there's no way to check if a va_list already has va_start called on it or not. And there's no guarantee that it will be called before being passed to your function, so I suspect this would have to be enforced by documentation and convention.

Post Deleted by MrHappyAsthma
added 481 characters in body
Source Link
MrHappyAsthma
  • 6.5k
  • 10
  • 53
  • 81

Yes, you should call va_start first.

Per the instructions in the documentation: va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg. (Source)

This is also confirmed on the va_arg documentation: Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end. (Source)

I would imagine not calling va_start is undefined behavior, but I couldn't find a specific callout to state as such. I would imagine it's not safe to rely on it working, even if it happened to run correctly in one demo.

Here's a good example from GNU:

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

int add_em_up (int count,...)
{
  va_list ap;
  int i, sum;

  va_start (ap, count);         /* Initialize the argument list. */

  sum = 0;
  for (i = 0; i < count; i++)
    sum += va_arg (ap, int);    /* Get the next argument value. */

  va_end (ap);                  /* Clean up. */
  return sum;
}

int main (void)
{
  /* This call prints 16. */
  printf ("%d\n", add_em_up (3, 5, 5, 6));

  /* This call prints 55. */
  printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  return 0;
}

Yes, you should call va_start first.

Per the instructions in the documentation: va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg. (Source)

Here's a good example from GNU:

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

int add_em_up (int count,...)
{
  va_list ap;
  int i, sum;

  va_start (ap, count);         /* Initialize the argument list. */

  sum = 0;
  for (i = 0; i < count; i++)
    sum += va_arg (ap, int);    /* Get the next argument value. */

  va_end (ap);                  /* Clean up. */
  return sum;
}

int main (void)
{
  /* This call prints 16. */
  printf ("%d\n", add_em_up (3, 5, 5, 6));

  /* This call prints 55. */
  printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  return 0;
}

Yes, you should call va_start first.

Per the instructions in the documentation: va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg. (Source)

This is also confirmed on the va_arg documentation: Prior to calling va_arg, ap must be initialized by a call to either va_start or va_copy, with no intervening call to va_end. (Source)

I would imagine not calling va_start is undefined behavior, but I couldn't find a specific callout to state as such. I would imagine it's not safe to rely on it working, even if it happened to run correctly in one demo.

Here's a good example from GNU:

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

int add_em_up (int count,...)
{
  va_list ap;
  int i, sum;

  va_start (ap, count);         /* Initialize the argument list. */

  sum = 0;
  for (i = 0; i < count; i++)
    sum += va_arg (ap, int);    /* Get the next argument value. */

  va_end (ap);                  /* Clean up. */
  return sum;
}

int main (void)
{
  /* This call prints 16. */
  printf ("%d\n", add_em_up (3, 5, 5, 6));

  /* This call prints 55. */
  printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  return 0;
}
Source Link
MrHappyAsthma
  • 6.5k
  • 10
  • 53
  • 81
Loading