Search code examples
c++visual-c++macrospredefined-macro

Why would __FUNCTION__ be undefined?


I have a C++ library that uses the predefined macro __FUNCTION__, by way of crtdefs.h. The macro is documented here. Here is my usage:

my.cpp

#include <crtdefs.h>
...
void f()
{
    L(__FUNCTIONW__ L" : A diagnostic message");
}

static void L(const wchar_t* format, ...)
{
    const size_t BUFFERLENGTH = 1024;
    wchar_t buf[BUFFERLENGTH] = { 0 };
    va_list args;
    va_start(args, format);
    int count = _vsnwprintf_s(buf, BUFFERLENGTH, _TRUNCATE, format, args);
    va_end(args);
    if (count != 0)
    {
        OutputDebugString(buf);
    }
}

crtdefs.h

#define __FUNCTIONW__ _STR2WSTR(__FUNCTION__) 

The library (which is compiled as a static library, if that matters) is consumed by another project in the same solution, a WPF app written in C#.

When I compile the lib, I get this error:

identifier "L__FUNCTION__" is undefined.

According to the docs, the macro isn't expanded if /P or /EP are passed to the compiler. I have verified that they are not. Are there other conditions where this macro is unavailable?


Solution

  • Just use

    L(__FUNCTION__    L" : A diagnostic message");
    

    When adjacent string literals get combined, the result will be a wide string if any of the components were.

    There's nothing immediately wrong with using L as the name of a function... it's rather meaningless however. Good variable and function identifiers should be descriptive in order to help the reader understand the code. But the compiler doesn't care.


    Since your L function wraps vsprintf, you may also use:

    L(L"%hs : A diagnostic message", __func__);
    

    since __func__ is standardized as a narrow string, the %hs format specifier is appropriate.


    The rule is found in 2.14.5p13:

    In translation phase 6 (2.2), adjacent string literals are concatenated. If both string literals have the same encoding-prefix, the resulting concatenated string literal has that encoding-prefix. If one string literal has no encoding-prefix, it is treated as a string literal of the same encoding-prefix as the other operand. If a UTF-8 string literal token is adjacent to a wide string literal token, the program is ill-formed. Any other concatenations are conditionally-supported with implementation-defined behavior.