Pracuję więc nad bardzo dużą bazą kodu, a ostatnio zaktualizowałem do gcc 4.3, która teraz wyzwala to ostrzeżenie:
ostrzeżenie: przestarzała konwersja stałej ciągu na „char *”
Oczywiście poprawnym sposobem jest znalezienie każdej takiej deklaracji
char *s = "constant string";
lub wywołanie funkcji, takie jak:
void foo(char *s);
foo("constant string");
i uczyń je const char
wskaźnikami. Oznaczałoby to jednak dotknięcie minimum 564 plików, co nie jest zadaniem, które chcę wykonać w tym momencie. Problem w tej chwili polega na tym, że biegam -werror
, więc potrzebuję sposobu, aby stłumić te ostrzeżenia. Jak mogę to zrobić?
Odpowiedzi:
Wierzę, że przejście
-Wno-write-strings
do gcc zniesie to ostrzeżenie.źródło
#pragma GCC diagnostic ignored "-Wwrite-strings"
.Wszelkie funkcje, do których przekazujesz literały łańcuchowe,
"I am a string literal"
powinny być używanechar const *
jako typ zamiastchar*
.Jeśli chcesz coś naprawić, napraw to dobrze.
Wyjaśnienie:
Nie można używać literałów łańcuchowych do inicjowania łańcuchów, które zostaną zmodyfikowane, ponieważ są one typu
const char*
. Casting dala constness aby później je modyfikować jest niezdefiniowane zachowanie , więc trzeba skopiowaćconst char*
ciągichar
przezchar
się dynamicznie alokowanychchar*
ciągów w celu ich modyfikacji.Przykład:
źródło
char *
/const char *
, więc w takim przypadku zwykle przesyłam.char*
nawet jak w przypadku ciągów, które nie zostaną zmodyfikowane. Jeśli weźmiesz parametr jakochar const*
i przekażesz go do standardowej funkcji, tochar*
trafisz w to. Jeśli funkcja biblioteki nie będzie manipulować ciągiem, możesz odrzucićconst
.Miałem podobny problem, rozwiązałem go w następujący sposób:
Czy to odpowiedni sposób na rozwiązanie tego? Nie mam dostępu do
foo
dostosowania go do akceptacjiconst char*
, chociaż byłoby to lepsze rozwiązanie (ponieważfoo
się nie zmieniam
).źródło
char **
wPyArg_ParseTupleAndKeywords
I zrobić coś takiego:static char kw[][16] = {"mode", "name", "ip", "port"}; static char * kwlist[] = {kw[0], kw[1], kw[2], kw[3], NULL};
Sprawdź obsługę gag Pragma diagnostyczna gcc oraz listę opcji ostrzeżeń -W (zmieniono: nowy link do opcji ostrzeżeń ).
W przypadku gcc możesz użyć
#pragma warning
dyrektyw, jak wyjaśniono tutaj .źródło
Jeśli jest to aktywna baza kodu, nadal możesz chcieć zaktualizować bazę kodu. Oczywiście ręczne wykonanie zmian nie jest możliwe, ale uważam, że ten problem można rozwiązać raz na zawsze za pomocą jednego
sed
polecenia. Jednak tego nie próbowałem, więc weź to z odrobiną soli.Może to nie znaleźć wszystkich miejsc (nawet nie biorąc pod uwagę wywołań funkcji), ale złagodziłoby problem i umożliwiło ręczne wykonanie kilku pozostałych zmian.
źródło
Nie mogę użyć przełącznika kompilatora. Więc zmieniłem to:
do tego:
źródło
Oto, jak to zrobić w pliku, abyś nie musiał modyfikować pliku Makefile.
Możesz później ...
źródło
Zastąpić
z
lub jeśli wywołujesz funkcję:
zamień to na
źródło
Zamiast:
To działa:
źródło
W C ++ użyj
const_cast
poniższych instrukcjiźródło
Test string
jest const string. Możesz więc rozwiązać w ten sposób:lub:
źródło
Dlaczego nie użyć po prostu rzutowania?
źródło
Wykonuj rzutowanie od stałego łańcucha do wskaźnika char, tj
źródło
W C ++ zamień:
z:
A jeśli chcesz to porównać:
źródło
Pracując z Arduino Sketch, miałem funkcję powodującą moje ostrzeżenia.
Aby zatrzymać ostrzeżenia, dodałem const przed char * str i char * sfind.
Wszystkie ostrzeżenia zniknęły.
źródło
zobacz tę sytuację:
obserwuj pole nazwy, w gcc kompiluje się bez ostrzeżenia, ale w g ++ zrobi to, nie wiem dlaczego.
źródło
Można również utworzyć zapisywalny ciąg ze stałej ciągu, wywołując
strdup()
.Na przykład ten kod generuje ostrzeżenie:
Jednak następujący kod nie robi tego (tworzy kopię ciągu na stercie przed przekazaniem go do
putenv
):W tym przypadku (i być może w większości innych) wyłączenie ostrzeżenia jest złym pomysłem - istnieje z jakiegoś powodu. Inna alternatywa (domyślnie domyślna możliwość zapisywania wszystkich ciągów) jest potencjalnie nieefektywna.
Posłuchaj, co mówi ci kompilator!
źródło
putenv()
jest napięty - nie jest to dobry wybór przykładu (przynajmniej nie bez większej ilości dyskusji na temat tego, coputenv()
robi, niż w tej odpowiedzi). To cała osobna dyskusja. (Zauważ, że specyfikacja POSIX dla zachowaniaputenv()
jest problematyczna, w oparciu o starsze implementacje sprzed zdefiniowania POSIX.) IIRC, wystąpił błąd w najnowszej (tej tysiącleciu) wersji biblioteki GNU C, która była związana zeputenv()
zmianą zachowania, i powrót do przeszłości.)po prostu użyj opcji -w dla g ++
przykład:
g ++ -w -o simple.o simple.cpp -lpthread
Pamiętaj, że nie pozwala to uniknąć wycofania, a raczej zapobiega wyświetlaniu ostrzeżenia na terminalu.
Teraz, jeśli naprawdę chcesz uniknąć utraty wartości, użyj słowa kluczowego const w następujący sposób:
źródło
Dlaczego nie skorzystasz z
-Wno-deprecated
opcji, aby zignorować przestarzałe komunikaty ostrzegawcze?źródło
To twój prawdziwy problem, IMO. Możesz wypróbować kilka zautomatyzowanych sposobów przejścia z (char *) na (const char *), ale nałożyłbym na nie pieniądze, nie tylko działając. Będziesz musiał zaangażować człowieka do przynajmniej części pracy. Krótko mówiąc, po prostu zignoruj to ostrzeżenie (ale IMO zostaw je włączone, bo nigdy nie zostanie naprawione) i po prostu usuń -Werror.
źródło
Dziękuję wszystkim za pomoc. Wybór z tu i tam pochodzi z tego rozwiązania. To się kompiluje. Nie przetestowałem jeszcze kodu. Może jutro...
Wiem, że w tablicy timeServer jest tylko 1 element. Ale może być więcej. Reszta została na razie skomentowana, aby zaoszczędzić pamięć.
źródło
obserwuj pole nazwy, w gcc kompiluje się bez ostrzeżenia, ale w g ++ zrobi to, nie wiem dlaczego.
w
gcc (Compiling C)
, -Wno-write-string jest domyślnie aktywne.w
g++ (Compiling C++)
-Wwrite-string jest domyślnie aktywneDlatego zachowuje się inaczej. Dla nas używanie makr
Boost_python
generuje takie ostrzeżenia. Więc używamy-Wno-write-strings
przy kompilacji C ++, ponieważ zawsze używamy-Werror
źródło
Deklaracja ciągu jako
const
rozwiąże problem:źródło