16 января 2012

Clang и разработка на Си

Рано или поздно, но скорее всего рано мы допускаем в коде ошибки которые не дают даже его скомпилировать. В таких случаях все просто, ведь компилятор с радостью укажет нам на эти ошибки, что бы мы их исправили. По мимо ошибок компилятор может указать нам на те части кода которые корректны с точки зрения синтаксиса но могут привести к неопределенным результатам.

Перейдем от слов к примеру:

#include <stdio.h>

int
main(int argc, char **argv)
{
  int i
  printf("i = %d\n", i);
  return 0;
}

gcc -c:

main.c: In function 'main':
main.c:7:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'printf'
main.c:7:22: error: 'i' undeclared (first use in this function)
main.c:7:22: note: each undeclared identifier is reported only once for each function it appears in

clang -c:

main.c:6:8: error: expected ';' at end of declaration
  int i
       ^
       ;
1 error generated.

Как видите, Clang смог точно указать нам где именно мы ошиблись, а именно где мы пропустили точку с запятой. Давайте мы исправим код и попробуем включить предупреждения флагами компиляции -Wall и -Wextra.

gcc -c -Wall -Wextra:

main.c: In function 'main':
main.c:4:10: warning: unused parameter 'argc' [-Wunused-parameter]
main.c:4:23: warning: unused parameter 'argv' [-Wunused-parameter]
main.c:7:9: warning: 'i' is used uninitialized in this function [-Wuninitialized]

clang -c -Wall -Wextra:

main.c:4:10: warning: unused parameter 'argc' [-Wunused-parameter]
main(int argc, char **argv)
         ^
main.c:4:23: warning: unused parameter 'argv' [-Wunused-parameter]
main(int argc, char **argv)
                      ^
main.c:7:22: warning: variable 'i' is uninitialized when used here
      [-Wuninitialized]
  printf("i = %d\n", i);
                     ^
main.c:6:8: note: initialize the variable 'i' to silence this warning
  int i;
       ^
        = 0
3 warnings generated.

Clang не только нам сказал где мы возможно ошиблись, но и предложил пути решения некоторых проблем.

Clang понимает большинство флагов GCC и может стать прекрасным помощником для во время разработки. При этом я не советую сбрасывать GCC в пропасть отчаянья, ведь остается еще gprof, который в Clang не поддерживаться.

Самое замечательное что Clang активно развивается и может стать вам очень хорошим помощником.


Небольшая подсказка для тех кто использует Scons.

env.Replace(CC = 'clang')