Is it safe to use va_list in exception-prone code?

后端 未结 3 2351
生来不讨喜
生来不讨喜 2021-02-20 01:32

Typical example:

void foo(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);

    // might throw, might not.  who knows.
    bar(fmt, args);

            


        
相关标签:
3条回答
  • 2021-02-20 02:07

    As mentioned above it is Undefined behavior by the c standard. Yet depending on your platform the marco can compile into different things, I see for me for example it just does args = 0; And va_list is a char*; In which case it seems that the end macro isnt doing anything critical. Nothing bad should happen except im not sure who will deallocate the args, but i don't know where they are allocated in the first place.

    I don't in any way recommend using this but sometimes crazy things are necessary for supporting legacy code. If you can use a try catch there then by all means do so.

    0 讨论(0)
  • 2021-02-20 02:13

    The C++ standard defers this to the C standard.

    C99 (draft) 7.15.1/1 tells us that:

    Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function.

    Thus if bar throws, you fail to execute the va_end and your program has undefined behavior. If you add a try/catch to make sure that va_end is always called as required then you should be fine. But do remember that you can't pass non-PODs as varargs so if you need to handle them, you would need an alternate mechanism anyway.

    A more C++-like alternative would probably be insertion operators (operator<<) as is seen in the various iostreams provided by the language.

    0 讨论(0)
  • 2021-02-20 02:22

    The C++ standard defers to the C standard for the specification of va_start et al. The C standard has this to say:

    7.15.1p1 ...Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function.

    Thus, if you exit the function by any means after calling va_start but before va_end, your program exhibits undefined behavior.

    Yes, wrapping bar in a try/catch would help.

    0 讨论(0)
提交回复
热议问题