Типы ссылок по умолчанию равны null, чтобы указать, что они не ссылаются на какой-либо объект. Следовательно, если вы попытаетесь получить доступ к объекту, на который ссылаетесь, а его нет, вы получите исключение NullReferenceException.
Для Ex:
SqlConnection connection = null;
connection.Open();
Когда вы запускаете это кода, вы получите:
System.NullReferenceException: Object reference not set to an instance of an object.
Вы можете избежать этой ошибки, например, следующим образом:
if (connection != null){
connection.Open();
}
Примечание. Чтобы избежать этой ошибки, вы всегда должны инициализировать свои объекты прежде чем пытаться что-либо сделать с ними.
Проблема заключается не в отсутствующем объявлении функции (который отсутствует, так как вы включили <math.h>
).
В этой проблеме отсутствует информация об отладке для sqrt
, которую вы фактически используете. Без этой информации об отладке GDB не знает, какой тип параметра перейти на sqrt()
и что он возвращает.
Вы можете получить требуемую информацию об отладке во многих дистрибутивах Linux, установив пакет libc-debuginfo. Вот что я вижу в такой системе:
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) b main
Breakpoint 1 at 0x400558: file t.c, line 6.
(gdb) r
Breakpoint 1, main () at t.c:6
6 printf("sqrt(3): %f\n", sqrt(3));
(gdb) p sqrt
$1 = {<text variable, no debug info>} 0x7ffff7b7fb50 <__sqrt>
Примечание: «no debug info»
(gdb) p sqrt(3)
$2 = 0
(gdb) p sqrt(3.0)
$3 = 0
Примечание: соответствует вашему поведению. Что sqrt
функции do имеют информацию об отладке?
(gdb) info func sqrt
All functions matching regular expression "sqrt":
File ../sysdeps/x86_64/fpu/e_sqrt.c:
double __ieee754_sqrt(double);
File s_csqrt.c:
complex double __csqrt(complex double);
File ../sysdeps/x86_64/fpu/e_sqrtf.c:
float __ieee754_sqrtf(float);
File w_sqrtf.c:
float __sqrtf(float);
File s_csqrtf.c:
complex float __csqrtf(complex float);
File ../sysdeps/i386/fpu/e_sqrtl.c:
long double __ieee754_sqrtl(long double);
File w_sqrtl.c:
long double __sqrtl(long double);
File s_csqrtl.c:
complex long double __csqrtl(complex long double);
File ../sysdeps/ieee754/dbl-64/mpsqrt.c:
void __mpsqrt(mp_no *, mp_no *, int);
File w_sqrt.c:
double __sqrt(double);
(gdb) p __sqrt
$4 = {double (double)} 0x7ffff7b7fb50 <__sqrt>
Примечание: __sqrt
имеет тот же адрес, что и sqrt
, но GDB знает его тип!
(gdb) p __sqrt(3)
$5 = 1.7320508075688772
(gdb) p __sqrt(3.0)
$6 = 1.7320508075688772
Можно резонно утверждать, что это ошибка в GDB. Не стесняйтесь создавать его в bugzilla .
Чтобы вызвать функцию без отладочной информации, вы должны явно указать gdb тип возвращаемого значения и аргументы, используя функцию-указатель функции. Итак, для вашего примера:
(gdb) print ((double (*) (double)) sqrt) (3)
$1 = 1.7320508075688772
#include <stdio.h>
#include <math.h>
int main()
{
printf("sqrt(3): %f\n", sqrt(3));
return 0;
}
Выход:
josh@josh-ubuntu:~/scratch$ ./a.out
sqrt(3): 1.732051
Возможно, вызов sqrt не поддерживается! Возможно, потому что это функция libc. Я не знаю глубинной причины, но следующий тест показывает интересное поведение:
double mysqrt(double x) { return sqrt(x) };
Затем в сеансе gdb:
(gdb) p mysqrt(3)
$1 = 1.7320508075688772
(gdb) p sqrt(3)
$2 = -1209775368
Я предсказываю, что вы не сделали #include <math.h>
Без объявления функции, C по умолчанию возвращает значение функции int
. Число с плавающей запятой может возвращаться как 0 в зависимости от размера вашего int. C также не знает, как преобразовать аргумент функции. Он по умолчанию передаст аргумент как любой тип, которым он является. Если вы передадите целое число в sqrt()
, оно не будет преобразовано в double, но функция sqrt()
будет интерпретировать битовый шаблон как double
.