Ich verwende strerror_r in einer Protokollierungshelferfunktion. Wie die man-Seite beschreibt, gibt es zwei Versionen dieser Funktion. Die POSIX-Version gibt einen int zurück. Die GNU-Version gibt eine Zeichenfolge (char *) zurück.Strerror_r ist falsch auf Alpine Linux
Als solche, so dass mein C++ Code mehr tragbar ist, ich einen Code-Block ähnlich wie diese haben:
char buffer[1000];
int size = 1000;
int result = 0;
char* msg = buffer;
buffer[0] = '\0';
#ifdef _GNU_SOURCE
msg = strerror_r(err, buffer, size);
#else
result = strerror_r(err, buffer, size);
if (result != 0)
{
sprintf(buffer, "unknown error: %d", err);
}
#endif
LogToFile(msg);
In dem obigen Code-Block, wird es entweder verwenden Version von strerror_r
auf Anwesenheit abhängig von _GNU_SOURCE
, die IMMER von g ++ festgelegt wird, da libstdC++ es erfordert. Auf Mac und anderen Unix-Versionen wird die POSIX-Version verwendet.
Jetzt funktioniert dieser Code für eine lange Zeit bis heute gut. Ein Benutzer versucht, meinen Code auf Alpine Linux und berichtete diese Compiler-Fehler heute auf der Linie strerror_r
main.cpp:16:21 error: invalid conversion from 'int' to 'char*' [-fpermissive]
Welche diese Linie bildet mit zu kompilieren:
#ifdef _GNU_SOURCE
msg = strerror_r(err, buffer, size);
Einen Höhepunkt auf dieser Plattform an den /usr/include/string.h
enthüllt die folgenden:
Welche scheint, dass egal, welche Compiler-Umgebung verwendet wird, die einzige deklarierte versio n von strerror_r ist die POSIX-Version, die einen int zurückgibt. Das erklärt, warum der Fehler aufgetreten ist.
Ohne Benutzern zu sagen, dass sie manuell #undef _GNU_SOURCE
oder die Quelle ändern, wie kann ich arbeiten, um dieses, so dass der Code tragbar sein weiter? Globales undefiniertes _GNU_SOURCE ist wahrscheinlich ein Nicht-Starter, da dies C++ ist (und wie oben erwähnt, von libstdC++ benötigt). Ich versuche zu sehen, ob es eine andere Makro-Kombination geben würde, für die ich testen könnte, aber ich bin nicht in der Lage, etwas Offensichtliches zu finden.
Die offizielle Makroprüfung (gemäß der Handbuch-Seite verlinkt auf) ist '(_POSIX_C_SOURCE> = 200112L || _XOPEN_SOURCE> = 600) &&! _GNU_SOURCE' ist wahr, wenn die POSIX-Version bereitgestellt wird, andernfalls wird die GNU-Version bereitgestellt. Das bedeutet, dass Ihre Überprüfung ausreichen sollte, um sicherzustellen, dass die GNU-Version bereitgestellt wird, und die C-Bibliothek in Alpine Linux scheint fehlerhaft oder veraltet zu sein. –
Wickeln Sie es in Ihrer eigenen Funktion. Machen Sie es flexibel genug, um beide Varianten zu verwenden. –
@ n.m. Kannst du es ausarbeiten? Es ist bereits in einer Funktion verpackt ... – selbie