Почему gcc сообщает "неявное объявление функции "round""?

у меня есть следующий код C:

#include <math.h>

int main(int argc, char ** argv)
{
    double mydouble = 100.0;
    double whatever = round(mydouble);

    return (int) whatever;
}

когда я компилирую это, я получаю предупреждения:

round_test.c: In function ‘main’:
round_test.c:6: warning: implicit declaration of function ‘round’
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’

Я ржавый с C, но я думал, что #include принес декларацию для round() в область действия. Я проверил свой стандарт ANSI (C99-единственная копия, которая у меня есть), который подтверждает, что функция round () существует в математике.заголовок сек. Я что-то упускаю?

Edit: компилятор GCC 4.3.2 на Ubuntu (intrepid, IIRC). Запуск gcc-E дает:

$ gcc -E round_test.c | grep round
# 1 "round_test.c"
# 1 "round_test.c"
# 2 "round_test.c" 2
    double whatever = round(mydouble);

таким образом, определение, очевидно, не находится в заголовках.

6 ответов


Я вижу, вы используете gcc.

по умолчанию gcc использует стандарт, аналогичный C89. Вы можете "заставить" его использовать стандарт C99 (части она соответствует)

gcc -std=c99 -pedantic ...

цитата руководство GCC

по умолчанию GCC предоставляет некоторые расширения языка C, которые на редких случаях конфликт с норматив. См. расширения для C языковая семья. Использование-std параметры, перечисленные выше, отключат эти расширения, где они конфликтуют с стандартной версии выбранной. Вы также можете выбрать расширенный версия языка C явно с-std=gnu89 (для C89 с GNU расширения) или-std=gnu99 (для C99 с расширениями GNU). По умолчанию, если нет вариантов диалекта языка C учитывая, is-std=gnu89; это изменится to-std=gnu99 в некотором будущем выпуске когда поддержка C99 полная. Некоторые функции, которые являются частью C99 стандарт принят как расширения в С89 режим.


что-то должно быть не так с вашей установкой gcc, системными заголовками или параметрами компиляции.

попробуйте скомпилировать с-E. Это покажет вам, что выводит препроцессор - включая, какие заголовки включаются и что в них. В моей системе Ubuntu Linux это около 1000 строк вывода, включая это:

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__));

вам нужно сказать gcc, что вы хотите C99, и что вы хотите связать в libm:

gcc -std=c99 -lm round_test.c

код, который вы вводите, компилируется чисто на MacOS X 10.5.8 с GCC 4.0.1. Если его подталкивают опции '- Wall - Wextra', он жалуется на неиспользуемые параметры argc и argv-не материал.

вы заглянули в <math.h> на вашей машине?

вы пробовали с такими параметрами, как'- stc=c99'?


C99 был ответом, но полная история немного сложнее. Причина, по которой я вообще играл с этим, заключалась в том, что я пытался скомпилировать библиотеку, написанную для Windows, которая имела свое собственное "оптимизированное" определение round(). Я получил ошибку компоновщика, сообщающую мне, что определение противоречит встроенному, поэтому я удалил определение (и объявление). Как только я это сделал, я начал получать "неявную ошибку объявления".

кажется, что режим компиляции по умолчанию (без флага-std=c99) не соответствует ни C89, ни C99: если он соответствует C89, вы должны иметь возможность предоставить пользовательское определение round() без конфликта, и если он соответствует C99, объявление должно быть в математике.h.


вам нужно связаться с математической библиотеки. Поэтому при компиляции обязательно добавьте -lm флаг.