• is it possible to have functions with 0, 1, or 2 args?

    From Mark Summerfield@21:1/5 to All on Mon Aug 5 08:26:04 2024
    Given

    ```
    // vaargs.h
    #pragma once

    #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
    #define NARGS_(_5, _4, _3, _2, _1, N, ...) N

    #define CONC(A, B) CONC_(A, B)
    #define CONC_(A, B) A##B

    // va_test.h
    #include "vaargs.h"

    #define va_test(...) CONC(va_test, NARGS(__VA_ARGS__))(__VA_ARGS__)
    int va_test0();
    int va_test1(int);
    int va_test2(int, int);

    // va_test.c

    #include "va_test.h"

    int va_test0() { return va_test2(3, 11); }
    int va_test1(int a) { return va_test2(3, a); }
    int va_test2(int a, int b) { return a + b; }

    // va_tests.c
    #include "va_test.h"
    #include <stdbool.h>
    #include <stdio.h>

    int main() {
    int i = va_test();
    if (i != 14) {
    fprintf(stderr, "FAIL: va_test() expecte 14 go %d\n", i);
    }
    i = va_test(5);
    if (i != 8) {
    fprintf(stderr, "FAIL: va_test() expecte 8 go %d\n", i);
    }
    i = va_test(2, 9);
    if (i != 11) {
    fprintf(stderr, "FAIL: va_test() expecte 11 go %d\n", i);
    }
    }
    ```

    This does *not* work for the `va_test()` call. But if I supply 1 or 2 args
    it works great.

    The rational is that I'd like to create a function `new_thing()` which
    takes an optional size, e.g.,

    ```
    thing new_thing0() { return new_thing1(10); }
    // above uses default size of 10
    thing new_thing1(int size) { ... }
    ```

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Mark Summerfield on Mon Aug 5 09:06:42 2024
    Mark Summerfield <mark@qtrac.eu> wrote or quoted:
    The rational is that I'd like to create a function `new_thing()` which
    takes an optional size, e.g.,

    I'm hella stoked on writing code that's chill in C. So,
    in a sitch like this, I might roll with a function that's
    /always/ down to take an argument and just hit it with a
    "-1" if I'm not trying to lock down a size.

    The "va_list" jazz in C, courtesy of the <stdarg.h> header, lets
    functions roll with a flexible number of args. It's like a buffet
    line for arguments, where you can scoop them up one by one using
    those gnarly macros "va_start", "va_arg", and "va_end".

    But here's the rub - the function's not psychic, so it can't just
    divine how many args are coming down the pike. You got to clue it in
    somehow, like passing a head count or dropping a hint about where to
    pump the brakes. The coder doesn't have to play bean counter though;
    he could just slap a "Dead End" sign at the tail of the arg parade!

    main.c

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

    int f( int const n, ... )
    { va_list args; /* to hold the variable arguments */
    va_start( args, n ); /* Initialize the "va_list" variable with the */
    int result; /* variable arguments, starting after n */
    switch( n )
    { case 0: result = f( 2, 3, 11 ); break;
    /* va_arg(args, int) retrieves the next argument from the "va_list"
    of type "int" */
    case 1: result = f( 2, 3, va_arg( args, int )); break;
    case 2:
    result = va_arg( args, int )+ va_arg( args, int ); break; }
    va_end( args ); /* Clean up the "va_list" */
    return result; }

    int main( void )
    { printf
    ( "%d\n", 14 == f( 0 )&& 8 == f( 1, 5 )&& 11 == f( 2, 2, 9 )); }

    transcript

    1

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Stefan Ram on Mon Aug 5 09:45:37 2024
    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:
    #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)

    Up top, C's totally buggin' about the diff between one argument
    and zilch, 'cause that comma in "__VA_ARGS__," is always chillin'
    there. We could 86 it with the fresh "__VA_OPT__(,)", but not
    all C implementations are down to clown with that yet . . .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Mark Summerfield on Mon Aug 5 09:32:25 2024
    Mark Summerfield <mark@qtrac.eu> wrote or quoted:
    This does *not* work for the `va_test()` call. But if I supply 1 or 2 args
    it works great.

    Here's an

    SSCCE, a short self-contained correct compilable example, aka,
    MWE - minimal working example.

    Some coders whip up these examples themselves for their post!

    It's a quick and dirty demo that can be compiled and run to
    show what's buggin' them.

    In this case, it's hella clear the macros are trippin', thinkin'
    the number of args is "1" when it's actually zilch, nada, zero.

    main.c

    #include <stdio.h>

    #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
    #define NARGS_(_5, _4, _3, _2, _1, N, ...) N
    #define va_test(...) NARGS(__VA_ARGS__)

    int main( void ){ printf( "%d\n", va_test() ); }

    transcript

    1

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to All on Mon Aug 5 15:19:46 2024
    On Mon, 05 Aug 2024 08:26:04 +0000
    Mark Summerfield <mark@qtrac.eu> wrote:

    According to my understanding, vararg functions without arguments will
    become possible in C23. But since fully functional C23 compilers do not
    exist yet, right now the answer to your question is "No".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Mark Summerfield on Mon Aug 5 14:04:45 2024
    Mark Summerfield <mark@qtrac.eu> wrote or quoted:
    Subject: Re: is it possible to have functions with 0, 1, or 2 args?

    FWIW, in math, there's no function that takes zero arguments.
    But in something called "universal algebra", there's a thing
    like that: so-called "operations of arity 0". (Basically, that's
    just a fancy term for a constant.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Blue-Maned_Hawk@21:1/5 to Mark Summerfield on Mon Aug 5 18:46:40 2024
    Mark Summerfield wrote:

    The rational is that I'd like to create a function `new_thing()` which
    takes an optional size, e.g.,

    ```
    thing new_thing0() { return new_thing1(10); }
    // above uses default size of 10 thing new_thing1(int size) { ... }
    ```

    If i were you, i would have put the desired end result first in the
    message and attempted solution afterwards, as i consider this to put the
    most relevant information first. I'm also pretty sure that whatever
    newsreader you're using is screwing up the line breaks in your message—i would recommend seeking a fix for that wherever you find support for your newsreader.

    With that out of the way…

    I question why you want a subroutine with “an optional size”. What does
    it do when the size _isn't_ given? If it does something completely
    different (e.g. creating only a partial object instead of a full object),
    i would just have two separate subroutines, one sized and one not. If it
    uses a default size, then i'd be worried about it causing problems in code written to use it being difficult to read later on because it hides
    information from the reader.

    Nevertheless, if you're undeterred, i think that you're on the right track
    with the macros that you've created. Luckily for you, it seems as though
    this appears to be a wheel that has already been invented: the P99 preprocessor library seems to define some macros that can apparently be
    used for such a thing: <https://gustedt.gitlabpages.inria.fr/p99/p99- html/group__default__arguments.html>

    As a side note, i don't know of a single newsreader that supports interpretation of markdown syntax in messages.

    --
    Blue-Maned_Hawk│shortens to Hawk│/blu.mɛin.dʰak/│he/him/his/himself/Mr. blue-maned_hawk.srht.site
    Consistent except for all the inconsistencies!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Stefan Ram on Wed Aug 7 23:04:31 2024
    On 5 Aug 2024 09:45:37 GMT, Stefan Ram wrote:

    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:

    #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)

    Up top, C's totally buggin' about the diff between one argument and
    zilch, 'cause that comma in "__VA_ARGS__," is always chillin'
    there. We could 86 it with the fresh "__VA_OPT__(,)", but not all C
    implementations are down to clown with that yet . . .

    Make sure to assume the B-Boy stance when you say that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Stefan Ram on Sun Aug 11 10:43:03 2024
    ram@zedat.fu-berlin.de (Stefan Ram) writes:

    Mark Summerfield <mark@qtrac.eu> wrote or quoted:

    This does *not* work for the `va_test()` call. But if I supply 1 or 2 args >> it works great.

    Here's an

    SSCCE, a short self-contained correct compilable example, aka,
    MWE - minimal working example.

    Some coders whip up these examples themselves for their post!

    It's a quick and dirty demo that can be compiled and run to
    show what's buggin' them.

    In this case, it's hella clear the macros are trippin', thinkin'
    the number of args is "1" when it's actually zilch, nada, zero.

    main.c

    #include <stdio.h>

    #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
    #define NARGS_(_5, _4, _3, _2, _1, N, ...) N
    #define va_test(...) NARGS(__VA_ARGS__)

    int main( void ){ printf( "%d\n", va_test() ); }

    transcript

    1

    It appears you have missed the point of the question. What is being
    sought is a way to distinguish between macro calls like va_test()
    and macro calls like va_test(x). The above definition of va_test()
    doesn't do that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Michael S on Sun Aug 11 22:20:36 2024
    Michael S <already5chosen@yahoo.com> writes:

    On Mon, 05 Aug 2024 08:26:04 +0000
    Mark Summerfield <mark@qtrac.eu> wrote:

    According to my understanding, vararg functions without arguments will
    become possible in C23. But since fully functional C23 compilers do not exist yet, right now the answer to your question is "No".

    Even in C99 varargs functions can be called without arguments.
    The question here is more subtle. In fact it is possible even
    in C99 and C11 to do what he wants, but it isn't easy, and it
    is far from obvious how to go about it. Still, if the question
    is "can this be done?", the answer is Yes even now.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Mark Summerfield on Sun Aug 11 22:15:52 2024
    Mark Summerfield <mark@qtrac.eu> writes:

    Given

    ```
    // vaargs.h
    #pragma once

    #define NARGS(...) NARGS_(__VA_ARGS__, 5, 4, 3, 2, 1, 0)
    #define NARGS_(_5, _4, _3, _2, _1, N, ...) N

    #define CONC(A, B) CONC_(A, B)
    #define CONC_(A, B) A##B

    // va_test.h
    #include "vaargs.h"

    #define va_test(...) CONC(va_test, NARGS(__VA_ARGS__))(__VA_ARGS__)
    int va_test0();
    int va_test1(int);
    int va_test2(int, int);

    // va_test.c

    #include "va_test.h"

    int va_test0() { return va_test2(3, 11); }
    int va_test1(int a) { return va_test2(3, a); }
    int va_test2(int a, int b) { return a + b; }

    // va_tests.c
    #include "va_test.h"
    #include <stdbool.h>
    #include <stdio.h>

    int main() {
    int i = va_test();
    if (i != 14) {
    fprintf(stderr, "FAIL: va_test() expecte 14 go %d\n", i);
    }
    i = va_test(5);
    if (i != 8) {
    fprintf(stderr, "FAIL: va_test() expecte 8 go %d\n", i);
    }
    i = va_test(2, 9);
    if (i != 11) {
    fprintf(stderr, "FAIL: va_test() expecte 11 go %d\n", i);
    }
    }
    ```

    This does *not* work for the `va_test()` call. But if I supply 1 or 2 args it works great.

    The rational is that I'd like to create a function `new_thing()` which
    takes an optional size, e.g.,

    ```
    thing new_thing0() { return new_thing1(10); }
    // above uses default size of 10
    thing new_thing1(int size) { ... }
    ```

    The short answer is, it is possible, from C99 onwards, to define a
    macro va_test(...) that does what you want. It isn't easy, but
    it is possible.

    If it's really important to define a macro that behaves like what
    you describe, and you can't find a suitable workaround, feel free
    to ask again and I can try to find and work through materials I
    have somewhere, to give an explanation of how to do what you want.
    Please note that I am making no guarantees about whether I can
    accomplish that, only that I can try to do so.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Harnden@21:1/5 to Tim Rentsch on Mon Aug 12 09:33:25 2024
    On 12/08/2024 06:20, Tim Rentsch wrote:
    Michael S <already5chosen@yahoo.com> writes:

    On Mon, 05 Aug 2024 08:26:04 +0000
    Mark Summerfield <mark@qtrac.eu> wrote:

    According to my understanding, vararg functions without arguments will
    become possible in C23. But since fully functional C23 compilers do not
    exist yet, right now the answer to your question is "No".

    Even in C99 varargs functions can be called without arguments.
    The question here is more subtle. In fact it is possible even
    in C99 and C11 to do what he wants, but it isn't easy, and it
    is far from obvious how to go about it. Still, if the question
    is "can this be done?", the answer is Yes even now.

    How does va_start know where to, um, start from if there's no last named argument?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Richard Harnden on Mon Aug 12 02:28:24 2024
    Richard Harnden <richard.nospam@gmail.invalid> writes:

    On 12/08/2024 06:20, Tim Rentsch wrote:

    Michael S <already5chosen@yahoo.com> writes:

    On Mon, 05 Aug 2024 08:26:04 +0000
    Mark Summerfield <mark@qtrac.eu> wrote:

    According to my understanding, vararg functions without arguments will
    become possible in C23. But since fully functional C23 compilers do not >>> exist yet, right now the answer to your question is "No".

    Even in C99 varargs functions can be called without arguments.
    The question here is more subtle. In fact it is possible even
    in C99 and C11 to do what he wants, but it isn't easy, and it
    is far from obvious how to go about it. Still, if the question
    is "can this be done?", the answer is Yes even now.

    How does va_start know where to, um, start from if there's no last
    named argument?

    Sorry, I meant to say macros, not functions (using ... and __VA_ARGS__).
    The original question is about macro definitions, not function
    definitions, and I didn't read carefully enough.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Harnden@21:1/5 to Tim Rentsch on Mon Aug 12 11:37:39 2024
    On 12/08/2024 10:28, Tim Rentsch wrote:
    Richard Harnden <richard.nospam@gmail.invalid> writes:

    On 12/08/2024 06:20, Tim Rentsch wrote:

    Michael S <already5chosen@yahoo.com> writes:

    On Mon, 05 Aug 2024 08:26:04 +0000
    Mark Summerfield <mark@qtrac.eu> wrote:

    According to my understanding, vararg functions without arguments will >>>> become possible in C23. But since fully functional C23 compilers do not >>>> exist yet, right now the answer to your question is "No".

    Even in C99 varargs functions can be called without arguments.
    The question here is more subtle. In fact it is possible even
    in C99 and C11 to do what he wants, but it isn't easy, and it
    is far from obvious how to go about it. Still, if the question
    is "can this be done?", the answer is Yes even now.

    How does va_start know where to, um, start from if there's no last
    named argument?

    Sorry, I meant to say macros, not functions (using ... and __VA_ARGS__).
    The original question is about macro definitions, not function
    definitions, and I didn't read carefully enough.

    No worries.

    So ... how can you do it with macros?

    And, even if it's possible, is it a good idea?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Richard Harnden on Mon Aug 12 15:39:10 2024
    Richard Harnden <richard.nospam@gmail.invalid> writes:

    On 12/08/2024 10:28, Tim Rentsch wrote:

    Richard Harnden <richard.nospam@gmail.invalid> writes:

    On 12/08/2024 06:20, Tim Rentsch wrote:

    Michael S <already5chosen@yahoo.com> writes:

    On Mon, 05 Aug 2024 08:26:04 +0000
    Mark Summerfield <mark@qtrac.eu> wrote:

    According to my understanding, vararg functions without arguments will >>>>> become possible in C23. But since fully functional C23 compilers do not >>>>> exist yet, right now the answer to your question is "No".

    Even in C99 varargs functions can be called without arguments.
    The question here is more subtle. In fact it is possible even
    in C99 and C11 to do what he wants, but it isn't easy, and it
    is far from obvious how to go about it. Still, if the question
    is "can this be done?", the answer is Yes even now.

    How does va_start know where to, um, start from if there's no last
    named argument?

    Sorry, I meant to say macros, not functions (using ... and __VA_ARGS__).
    The original question is about macro definitions, not function
    definitions, and I didn't read carefully enough.

    No worries.

    So ... how can you do it with macros?

    I'm still working on preparing an answer to that question.

    And, even if it's possible, is it a good idea?

    An excellent question. I expect there are two schools of thought. :)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)