2016-07-19 22 views
7

So habe ich diesen Code-SnippetKönnen Sie __func__ in eine wchar_t [] zur Kompilierzeit konvertieren?

wchar_t funcName[] = __FUNCTIONW__; 

aber das Problem mit __FUNCTIONW__ ist es Klasse Info im Namen hat, wenn alles, was ich will, ist der Name der Funktion. Jetzt __FUNCTIONW__ nennt nur _CRT_WIDE(__FUNCTION__) die ich denke ich _CRT_WIDE(__func__) nennen könnte, aber das gibt einen Fehler „Kennung L__func__ nicht definiert ist“

__func__ ist eine implizit deklarierte Kennung, die ein Zeichenarray Variable erweitert mit dem Funktionsnamen, wenn es im Innern verwendet wird, einer Funktion. Es wurde zu C in C99 hinzugefügt. Von C99 §6.4.2.2/1:

Die Kennung __func__ wird implizit durch den Übersetzer erklärt, als ob unmittelbar nach der öffnenden Klammer jeder Funktionsdefinition, die Deklaration

static const char __func__[] = "function-name"; 

erschien, wo Funktion -name ist der Name der lexikalisch umschließenden Funktion. Dieser Name ist der schmucklose Name der Funktion.

Ich nehme das zu __func_ ist kein Makro und es hat nichts mit Vorverarbeitung zu tun?

Gibt es eine andere Möglichkeit, ein Array wchar_t zur Kompilierzeit zu bekommen?

+0

Richtig, '__func__' ist kein Makro, und ein" L "davor als' _CRT_WIDE'-Makro anzuhängen, verursacht einen Fehler. –

+0

Aus dem gleichen Grund können Sie keine String-Verkettung à la '" Hallo, mein Name ist "__func__". "... – Aconcagua

Antwort

1

Wie Sie den C-Standard bereits zitierten (eigentlich ist es die schlechte, müssen Sie ++ Standard-C, aber es finden Sie das gleiche ...):

static const char __func__[] = "function-name"; 

Sie haben jetzt das gleiche Problem wie wenn Sie wollten jedes beliebige andere Array zur Kompilierzeit konvertieren, z. z. B.

char buffer[16]; 
// convert to wchar_t[16]? 

int array[4]; 
// convert to double[4]? 

Art der Anordnung ist int[4]. Das ist fix. Es belegt 4 * sizeof (int) Bytes im Speicher, typischerweise 16 Bytes für die meisten der heutigen Maschinen, die man nicht magisch in 4 * sizeof (double) Bytes, typischerweise 32 Bytes ändern kann (wäre ein schöner Trick um einen Speicher zu bekommen) Upgrade kostenlos ...).

Es gibt keine Möglichkeit, char const __func__[] in eine wchar_t[] zur Kompilierzeit zu ändern, sorry. Auf der anderen Seite, sollten Sie die gewöhnlichen char const Array __func__ in vielen Orten nutzen können würden Sie die Wchar_t Array verwenden (das Array, nicht die breite Stringliteral!):

std::wofstream ws; ws << __func__; 
wchar_t buffer[64]; swprintf(buffer, sizeof(buffer), L"%s\n", __func__); 

Problem sein wird, mit Funktionen zu akzeptieren e. G. wchar_t *, während keine char * Überladung vorliegt. Dann werden Sie nicht um die Umwandlung der Zeichenfolge zur Laufzeit kommen (siehe mbstowcs).

Wenn es hilft, könnte dies eine Idee, wie zu tun ist es bequem nur einmal pro Funktion:

template <size_t N> 
struct F 
{ 
    wchar_t name[N]; 
    F(char const* func) 
    { 
     mbstowcs(name, func, N); 
    } 
}; 
#define F_INIT static F<sizeof(__func__)> func(__func__) 
#define FUNC func.name 

void foo() 
{ 
    F_INIT; 
    std::wcout << FUNC; 
} 

int main(int argc, char* argv[]) 
{ 
    F_INIT; 
    std::wcout << FUNC; 
    return 0; 
} 

Gib ihnen (Vorlage + Makros), was Namen Sie am besten geeignet erscheint ...

+0

Wow, das ist sehr clever, wenn man statische var decls innerhalb von Funktionen nutzt. auch in meiner Arbeit herum konvertierte ich zu wstring und dann zu wchar_t * mit std :: wstring_convert > Konverter; std :: wstring ws_func = konverter.from_bytes (_ _func_ _); Erwähnen Sie nur, dass der letzte Teil b \ c Ich frage mich, ob die Struktur und Vorlage würde benötigt werden, wenn ich nur die Dienstprogramme auf Std :: wstring und std :: wstring_convert – user1881587

+2

Ein anderer Weg zu gehen, aber tun Sie es so: 'statische Std :: wstring ws_func (std :: wstring_convert >(). aus_bytes (__ func __)); 'Als statisch wird es nur einmal konstruiert. Der Konverter, wie er nur im ctor des wstring verwendet wird, wird auch nur einmal konstruiert. Keine Notwendigkeit für eine Vorlage oder gewöhnliche Struktur auf diese Weise. – Aconcagua

+0

Es gibt einen einfacheren Weg. Was für die Datei funktioniert (https://stackoverflow.com/a/14421702/2532437), funktioniert auch für die Funktion. Und das macht der Compiler es tun. Nicht einmal eine Laufzeit Anruf zu mbstowcs. –

Verwandte Themen