2014-02-10 3 views
4

Я не понимаю, как и когда вызывается вызов этой предопределенной функции sqrt(), также в случае, если я определяю свою собственную функцию sqrt(), она показывает ошибку компиляции, поэтому почему -определенный вызов функции работает, и вызов пользовательской функции не выполняется, хотя оба кода находятся в разделе (ТЕКСТ) моего исполняемого файла.предопределенная функция, называемая до начала

#include<stdio.h> 

int x = sqrt(16); 

int main() 
{ 

    printf(" x = %d\n",x); 
    return 0; 
} 

ВЫВОД:

x = 4; 

Когда я звоню SQRT() функция, определенная мной, я получаю следующее сообщение об ошибке, но та же ошибка does'nt появляется, когда я использую предопределенный функцию

ОШИБКА: инициализатор элемент не является постоянным

+2

Вы отметили этот вопрос как C, так и C++. Это два разных языка с разными правилами инициализации переменных. –

+0

Кроме того, вы не скажете _which_ ошибку компиляции, которую вы получаете. Я вижу две возможности, в зависимости от того, удаляете ли вы включение math.h или нет, когда вы определяете свою функцию sqrt и как эта функция записывается. –

ответ

8

Если вы определили свою собственную sqrt функцию, он будет конфликтовать с одной уже определен в math.h, ergo ошибка.

Вызов выполнен из-за того, что перед входом в значение main выполняются глобальные переменные (или, скорее, переменные области пространства имен) - это инициализация x.

+0

НЕТ, фактически имя функции не имеет значения, даже если я изменю имя, которое он не работает. Мой вопрос заключается в том, когда мой исполняемый файл создан, он содержит код для предопределенной функции, и он вызывается перед именем main() и значением, присвоенным «X», аналогично, если я пишу свою собственную функцию, она также должна работать, я имею в виду, что проблема с этим. – curious

+0

@curious вы можете использовать директивы препроцессора для своей проблемы. –

+0

@curious Вы заявили о своей функции перед ее использованием? –

0

Он говорил, что одна функция под названием SQRT() определяется еще уже (math.h имеет свое заявление)

при добавлении файла заголовка math.h он содержит объявление для функции SQRT(), который находится в библиотеке, которая будет добавлена ​​при связывании.

при попытке определить свою собственную функцию с тем же именем компилятором запутается, на котором функцию для вызова (ваш: или один уже объявлено в math.h)

Изменить имя функции для my_sqrt() она должна работайте отлично, когда вы определяете и звоните.

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

+0

На самом деле я не включил в свой код, я просто написал здесь, чтобы быть более явным. Мой вопрос для вас такой же, как я спросил в ответе выше – curious

0

Ошибка, которую вы получаете, вызвана причиной, по которой Лучиан объяснил выше.

Чтобы быть точным с вашей проблемой, вам нужно знать Preprocessor Directives.

Preprocessor directives are lines included in the code of programs preceded by a hash sign (#). These lines are not program statements but directives for the preprocessor. The preprocessor examines the code before actual compilation of code begins and resolves all these directives before any code is actually generated by regular statements.

Вы можете просто определить й перед входом главной функции:

#define x BLAH 

Я думаю, что это будет ясно немного ваши мысли. Cheerss!

+0

Что? Я вообще не понимаю этого ответа. –

+0

Я объясняю немного препроцессорной директивы здесь. Позвольте мне добавить больше разъяснений для лучшего понимания. –

+1

Я все еще смущен. Что должны делать препроцессорные директивы с этим вопросом? –

5

В C инициализатор переменной со статической продолжительностью хранения (что означает, что он присутствует в течение всего времени жизни программы, например, x) должен быть постоянным выражением. Вызов функции не является постоянным выражением, и вы получите ошибку компилятора, например (от GCC) ошибка: элемент инициализации не является константой. В стандарте также говорится, что «реализация может принимать другие формы постоянных выражений», поэтому для компилятора разрешено принимать вызов библиотечной функции, такой как sqrt в качестве постоянного выражения.Компилятор знает, что делает sqrt, и может даже оценить его во время компиляции и заменить вызов функции своим результатом.

C++ имеет разные правила, и там вы можете вызывать функции, даже ваши собственные функции, при инициализации x.

+0

Maybeeeeee, изначально я думал то же самое, но библиотеки находятся в форме двоичных файлов, трудно представить, как это делает компилятор, потому что он должен запустить этот код и получить результат (это единственный способ, возможно), я серьезно сомневаюсь в этом делает так. можете ли вы предоставить несколько ссылок? – curious

+1

@curious: утверждения об инициализаторах и константных выражениях относятся к (от моего бесплатного черновика) стандартного документа, но если вы хотите ссылаться на то, как работает GCC, я могу ссылаться только на документацию и исходный код GCC. Однако я использовал ** nm **, чтобы отобразить символы, содержащиеся в скомпилированном исполняемом файле вашей программы, и одну программу, которая вызывает ** sqrt ** с переменной как аргумент, а в то время как последняя программа содержит символ ** sqrt @@ GLIBC_2.2.5 **, ваша программа не указала, что указывает на то, что вызов ** sqrt ** в вашей программе был удален компилятором. –

+1

В конце концов, GCC - это программа на C, и он может вызывать ** sqrt **, как и любую другую программу на C. –

0

Попробуйте определить функцию в другом файле и включить файл здесь. Или просто объявите функцию до иналинизации

+0

нет, он все еще не работает. – curious

+0

Попробуйте определить перед вызовом – balaji

+0

Нет, нет прогресса – curious

1

Компилятор Gcc компилирует исходный файл процедурно.

Use g++ or c++ compiler.The code will work perfectly

Я скомпилировал код, используя компилятор g ++, и компиляция прошла успешно.

#include<stdio.h> 
int mysqrt(int n) 
{ 
return(n); 
} 
int a=mysqrt(10); 

int main() 
{ 
printf("%d",a); 
return(0); 
} 

Пожалуйста, игнорируйте внутреннюю логику функции mysqrt. Это просто для целей тестирования.

Насколько мне известно, это проблема с gcc-компилятором.

пункт 6.6, пункт 3 стандарта говорит

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.

, что постоянное выражение не должно содержать вызов функции, которое вычисляется.

Это потому, что

A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.

НКУ компилятор способен оценить постоянный экспресс, выполняя функцию библиотеки в time.But компиляции он не в состоянии оценить постоянный экспресс, выполнив определенный пользователь функцию во время компиляции time. Но компиляторы g ++ и C++ могут выполнять эту работу.

Смежные вопросы