M_PI недоступен с gcc --std = c11, но с --std = gnu11?

Я заметил, что M_PI недоступен на c11. Посмотрев на /usr/include/math.h я вижу, что M_PI определяется, если:

#if !defined(__STRICT_ANSI__) || ((_XOPEN_SOURCE - 0) >= 500)
...
#define M_PI 3.1415...
#endif 

Более того, в math.h из glibc __STRICT_ANSI__ заменяется на __USE_MISC. Я полностью потерял это.

Какова история между --std=c11 и константами, определенными в math.h?

Какой libc следует учитывать при распределении debian?

Кстати, M_PI определяется в c99 и gnu11...

Ответ 1

Это просто: M_PI не определен в стандарте C. Укажите свое собственное определение, если вы хотите быть стандартным.

Компиляторы C не могут вводить такие константы без нарушения законных программ на C (имя не зарезервировано и может использоваться как идентификатор), и поэтому они определяются только как расширение.

GCC 4.9 при использовании с -std=c99 не определяет M_PI, но при использовании с -std=gnu99

Ответ 2

Если вы хотите, чтобы M_PI искал более полный ответ с макросами тестов POSIX/XOPEN и т.д., Промежуточное решение:

#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif

Этот формат "1.20", который также достаточен для представления "туда и обратно" для 80-битного расширенного типа. двойная точность - "1,16". Для 128-битной четырехмерной точности:

#define M_PI (3.14159265358979323846264338327950288)

Формат "1.35" для точности округления. Это означает, что если вы хотите распечатать двойной символ с плавающей запятой и восстановить его, когда вы его прочитаете, вы должны использовать "% +1.16" для функций printf, так как это включено. Вы можете сказать, что double не имеет 17 значащих цифр, но эти цифры не являются "мусорными", если вы хотите восстановить значение.

Во всяком случае - есть лучшие ресурсы, чем это доступно.

Ответ 3

Макрос M_PI не определяется стандартом C11: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf

Поэтому защита #if защищает вас от проблем, если вы хотите определить свой собственный макрос M_PI. gcc делает именно то, что нужно. Стандартные заголовки не должны произвольно определять макросы, которые не соответствуют стандарту.