piątek, 31 stycznia 2014

Dziwny błąd, jeszcze dziwniejsze rozwiązanie

Przypadkiem dowiedziałem się, że brak przecinka między dwoma łańcuchami jest poprawnym wyrażeniem C. Co zabawniejsze, oznacza konkatenację.

Weźmy taki przykład:

char* tab[] = { "Ala", "ma", "kota", "imieniem" "Filemon" };


zatem tab[4] powoduje segfault, ale program się całkiem zacnie skompiluje.

Zapominając o przecinku można się tyyyle nauczyć ;)
Edit: W GCC nawet dołączenie -ansi -pedantic -Wall nie powoduje pojawienia się ostrzeżenia.

4 komentarze:

  1. > W GCC nawet dołączenie -ansi -pedantic -Wall nie powoduje pojawienia się ostrzeżenia.
    Bo to feature. :)

    OdpowiedzUsuń
    Odpowiedzi
    1. ; )
      Akurat wolałbym, aby było to widziane jako ostrzeżenie, bo zazwyczaj niejawna konkatenacja przy inicjalizacji tablicy nie pachnie niczym zaplanowanym.

      Usuń
    2. Warto więc rozejrzeć się za dodatkowym zestawem narzędzi. Podejrzewam, że sporo narzędzi do statycznej analizy kodu bez problemu wyłapało by tego typu niuanse jako potencjalny problem, a już na pewno próbę odwołania się do elementu poza jej zakresem.

      Zainstalowałem cppcheck i bez problemu zdiagnozował problem. Valgrind też by sobie poradził ale już w czasie wykonania (idealne również do testowania kodu, który korzysta z dynamicznych zasobów).

      I niestety liczenie na segfault jest naiwne. Przy statycznych tablicach jest bardziej niż prawdopodobne, że nie otrzymasz tego typu błędów. :)

      Dlatego zamiast marudzić na feature języka trzeba znaleźć narzędzie lub strategię, która pozwoli tego typu błędy ograniczać i wychwytywać z wyprzedzeniem. Niestety C/C++ jest naszpikowany tego typu pułapkami, a nikt tego nie zmieni ze względu na wydajność i kompatybilność (niekoniecznie w tej kolejności).

      Usuń
  2. Wiele rzeczy by sie nie kompilowalo, taka konkatenacja o ile srednio uzyteczna przy normalnym kodowaniu, jest czesto uzywana w makrach - i dlatego pewnie pedantic o niej nie ostrzega.

    OdpowiedzUsuń