Хедеры надо читать. Собирайте с #define _XOPEN_SOURCE 600 перед #include <math.h>
Пример:
#include <math.h>
int main (void)
{
double foo = M_PI;
}
Собираем:
$ gcc -std=c99 main.c
main.c: In function ‘main’:
main.c:5: error: ‘M_PI’ undeclared (first use in this function)
$ gcc -std=c99 -D_XOPEN_SOURCE=600 main.c
$
(всё ок)
Так короче, если писать не POSIX-код, а нестандартный GNU-код. Для POSIX надо делать -D_POSIX_C_SOURCE=..., и _XOPEN_SOURCE тоже из этой оперы. Во многих (серьёзных) проектах можно найти эти макросы в Makefile'ах. Стандарт требует, и с переносимостью проблем меньше.
> Для POSIX надо делать -D_POSIX_C_SOURCE=..., и _XOPEN_SOURCE
Поясню, что тут дело в том, что в стандарте POSIX используются некоторые имена заголовочных файлов, совпадающие со стандартом языка C (например, time.h), и поэтому если в gcc задать строгое соответствие стандарту (--std=c99, например), то POSIX-определения в таких заголовочных файлах будут невидны, если не задать явно эти макросы.