Zwracanie wskażnika do argumentu (const)

Zwracanie wskażnika do argumentu (const)
M1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 18
0

Witam,

Chcę napisać własną implementację funkcji strstr. Chcę zachować takie same typy argumenów i wartości zwracanej. Jak dotąd utknąłem na samym początku, z prostej przyczyny.

Kopiuj
 char *strstr(const char *s1, const char *s2) {
    if (!*s2) {
        return s1;
    }
}

Koduję w Clion i od razy krzyczy mi, że robię źle, gdyż argument jest stałą, a ja zwracam wskażnik do niego, co łamie zasadę "stałości". Oczywiście mogę to rzutować:

Kopiuj
char *strstr(const char *s1, const char *s2) {
    if (!*s2) {
        return (char *) s1;
    }
} 

I teraz pytanie. Co jest lepsze z punktu widzenia dobrych praktyk, co jest bardziej "profesjonalne" i milej widziane. Nie wiem do końca, czy rozumieć, że const jest tylko w obrębie funkcji, a co potem zrobię poza funkcją to moja sprawa, czy słowo kluczowe const przy argumencie zobowiązuje mnie także do pewnych przedsięwzięć poza nią. Oczywiście oba sposoby działają (u mnie ;)). Może jest to zależne od kompilatora?

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
3

Zwracaj char const*, zamiast zdradziecko zwracać błędny typ.

Kopiuj
char * str = strstr("blah","a");
str[0] = 'b'; // UB, crash

Dzięki const castowi w powyższym uniemożliwiłeś wychwycenie błędu w czasie kompilacji.

M1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 18
0

Oczywiście można tak zrobić. Pytanie dlaczego funkcja z biblioteki nie zwraca consta tylko ma taką implementację jak napisałem powyżej?

kq
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
0

Bo prototypy funkcji z biblioteki standardowej pamiętają lata 80-te, gdy const nie istniało w języku.

Xupicor
  • Rejestracja: dni
  • Ostatnio: dni
0

Gdyby to było C++ to bym powiedział, że w strstr albo masz i argumenty i typ zwracany const, albo żadne z nich, no i że odrzucanie const w C++ to grzech.
No ale to jest C, gdzie const niby już jest, ale potraktowane po macoszemu, a strstr - staaara funkcja - istniała kiedyś w wersji char* strstr(char*, char*), zanim przyszło const, a teraz istnieje w takiej jak napisałeś - przyjmujące argumenty jako const i zwracające wskaźnik bez const...
Mój zmysł estetyczny podpowiada, że takie odrzucanie brzydkie, ale wyjścia nie masz, musisz rzutować. To znaczy - nie masz, jeśli chcesz się trzymać typu z biblioteki standardowej.

Odpowiedzialność jest tutaj - jak zwykle w C i C++ - po stronie programisty. Jeśli zrobisz coś głupiego jak poniżej, to już Twoja wina:

Kopiuj
char* c = strstr("abecadlo", "cad");
c[0] = 'r'; // ups!

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.