Optional arguments in C function

后端 未结 3 929
小鲜肉
小鲜肉 2021-02-08 02:44

In a C function, I want to check if an input argument (\'value\' in my case) is presented or not.

i.e.:

void Console(char string[], int32_t value)
{
             


        
3条回答
  •  鱼传尺愫
    2021-02-08 03:17

    This sounds as if you are trying to use hackery to potentially facilitate yourself or whomever opened your source code "in write mode". I say "in write mode" (not read/write) because such code is very hard to read, because of all the hidden code, because of the magical macros you would need. C is not a smart language. The compilers might be smart, but the language semantics are rather pedantic. You should strictly comply with the rules, otherwise you are risking to make bad software or worse - not working at all.


    The "correct" way to do this, without creating a whole new programming language is to provide two arguments, and when the second should not be used, it should either be passed as NULL if it is a pointer or some excluding number such as -1 if it is a numeral type.

    Another approach is to create two separate functions with hinting names such as: console and console_full. Respectively with one and two arguments.

    But if you are still not comfortable with the aforementioned approaches, you can include stdarg.h to do it for you.

    void Console (char *string, ...) /* Note the ... */
    {
        va_list param;
        int32_t optValue = (-1); /* -1 would indicate optValue is to be ignored */
    
        // write string here
    
        va_start(param, string);
    
        optValue = va_arg(param, int32_t);
    
        if(optValue != (-1))
        {
            /* Work with `optValue` */
        }
    
        va_end(param);
    }
    

    Which way is not good, because you don't know the types of the additional arguments, neither you know how many are they. To know those things, you should do as printf-alike functions do, parse specific tokens inside the string that suggest an argument exists and what type of argument it is or at least just use a const variable counter of arguments. You can macrofy further that the counting of arguments is automatic.


    Update:

    You don't really need stdarg to use variadic functionality in C as this is a built-in feature. The C pre-processor can also expand variadic arguments (Although probably not in all versions). The libary stdarg provides those helpful macros, but you can implement them on your own as well. Note that not using a standard library is almost always the wrong thing. Just grab the address of the first (reference) variable, advance it with the size of the pointer and you have the address of the next argument (presumably). Something like:

    #include 
    
    #define INIT_VARARG(x,ref)          void* x = &ref
    #define GET_NEXT_VARARG(ptr,type)   (*((type* )(ptr+=sizeof(ptr))))
    
    void func (int ref, ...) // ref must be the number of int args passed.
    {
        INIT_VARARG(ptr,ref);
        int i;
    
        for(i = 0; i < ref; i++)
        {
            printf("[%i]\n", GET_NEXT_VARARG(ptr, int));
        }
    }
    
    int main (void)
    {
        func(3, 10, 15, 20);
    
        return 0;
    }
    

    You may use this for experimental purposes only. A good, secure and well-designed C code should not have such macros and should use stdarg instead.

提交回复
热议问题