Dlaczego konwersja ze stałej łańcuchowej na 'char*' jest prawidłowa w C, ale nieprawidłowa w C++
Standard C++11 (ISO/IEC 14882:2011) mówi w § C.1.1
:
char* p = "abc"; // valid in C, invalid in C++
Dla C++ jest to OK, ponieważ wskaźnik do literału Łańcuchowego jest szkodliwy, ponieważ każda próba jego modyfikacji prowadzi do awarii. Ale dlaczego jest ważny w C?
C++11 says also:
char* p = (char*)"abc"; // OK: cast added
Co oznacza, że jeśli Obsada zostanie dodana do pierwszego twierdzenia, staje się ważna.
Dlaczego casting sprawia, że druga instrukcja jest ważna w C++ i czym różni się od pierwszej? Czy to nie jest wciąż szkodliwe? Jeśli tak, to dlaczego standard powiedział, że jest OK?
4 answers
W C++03, twój pierwszy przykład był poprawny, ale użyto przestarzałej konwersji domyślnej-literał Łańcuchowy powinien być traktowany jako typ char const *
, ponieważ nie można modyfikować jego zawartości (bez powodowania niezdefiniowanego zachowania).
Począwszy od C++11, domyślna konwersja, która została wycofana, została oficjalnie usunięta, więc kod, który od niej zależy (jak w Twoim pierwszym przykładzie), nie powinien już się kompilować.
Zauważyłeś jeden sposób, aby umożliwić kompilację kodu: chociaż Ukryty konwersja została usunięta, konwersja Jawna nadal działa, więc możesz dodać obsadę. Ja bym nie rozważał jednak to "naprawianie" kodu.
Naprawa kodu wymaga zmiany typu wskaźnika na właściwy typ:
char const *p = "abc"; // valid and safe in either C or C++.
Dlaczego było dozwolone w C++ (i nadal jest w C): po prostu dlatego, że jest dużo istniejącego kodu, który zależy od tej ukrytej konwersji, i łamanie tego kodu (przynajmniej bez jakiegoś oficjalnego Ostrzeżenia) najwyraźniej standardowe komitety uznały to za zły pomysł.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-06 07:12:11
Jest ważny w C ze względów historycznych. C tradycyjnie określał, że typ literału łańcuchowego to char *
, a nie const char *
, chociaż kwalifikował go mówiąc, że nie można go modyfikować.
Kiedy używasz cast, zasadniczo mówisz kompilatorowi, że znasz lepiej niż domyślne reguły dopasowywania typów, a to sprawia, że przypisanie jest OK.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-06 07:10:31
Możesz również użyć strdup :
char* p = strdup("abc");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-11 05:24:50
Możesz zadeklarować jako jedną z poniższych opcji:
char data[] = "Testing String";
Lub
const char* data = "Testing String";
Lub
char* data = (char*) "Testing String";
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-26 10:04:48