Случается, когда вы пытаетесь вызвать функцию, которая еще не определена. Общие причины включают отсутствующие расширения и включают в себя объявление условной функции, функцию в объявлении функции или простые опечатки.
Пример 1 - Декларация условной функции
$someCondition = false;
if ($someCondition === true) {
function fn() {
return 1;
}
}
echo fn(); // triggers error
В этом случае fn()
никогда не будет объявлено, потому что $someCondition
не соответствует действительности.
Пример 2 - Функция в объявлении функции
function createFn()
{
function fn() {
return 1;
}
}
echo fn(); // triggers error
В этом случае fn
будет объявлен только после вызова createFn()
. Обратите внимание, что последующие вызовы createFn()
вызовут ошибку об обновлении существующей функции.
Вы также можете увидеть это для встроенной функции PHP. Попробуйте найти функцию в официальном руководстве и проверьте, к какому «расширению» (к нему принадлежит PHP-модуль), и какие версии PHP поддерживают его.
В случае отсутствующее расширение, установите это расширение и включите его в php.ini. Обратитесь к Инструкции по установке в Руководстве по PHP для расширения вашей функции. Возможно, вы также сможете включить или установить расширение с помощью диспетчера пакетов (например, apt
в Debian или Ubuntu, yum
в Red Hat или CentOS ) или панель управления в среде общедоступного хостинга.
Если функция была введена в более новой версии PHP из того, что вы используете, вы можете найти ссылки на альтернативные реализации в руководстве или в разделе комментариев , Если он был удален из PHP, найдите информацию о том, почему, поскольку это может быть уже не нужно.
В случае отсутствия включено, обязательно включите файл, объявляющий функцию перед вызовом функции.
В случае опечаток исправить опечатку.
Вопросы, относящиеся
NULL
указатель memcpy
для копирования перекрывающихся буферов . int64_t i = 1; i <<= 72
не определено) int i; i++; cout << i;
) volatile
или sig_atomic_t
в получении сигнала long int
#if
выражение Порядок, что параметры функции оценены, неуказанный поведение . (Это не заставит Вашу программу разрушить, взорвать или заказать пиццу..., в отличие от этого неопределенный поведение .)
единственное требование - то, что все параметры должны быть полностью оценены, прежде чем функция вызвана.
<час>Это:
// The simple obvious one.
callFunc(getA(),getB());
Может быть эквивалентно этому:
int a = getA();
int b = getB();
callFunc(a,b);
Или это:
int b = getB();
int a = getA();
callFunc(a,b);
Это может быть также; это до компилятора. Результат может иметь значение, в зависимости от побочных эффектов.
Компилятор является бесплатным переупорядочить части оценки выражения (предполагающий, что значение неизменно).
От исходного вопроса:
a[i] = i++;
// This expression has three parts:
(a) a[i]
(b) i++
(c) Assign (b) to (a)
// (c) is guaranteed to happen after (a) and (b)
// But (a) and (b) can be done in either order.
// See n2521 Section 5.17
// (b) increments i but returns the original value.
// See n2521 Section 5.2.6
// Thus this expression can be written as:
int rhs = i++;
int lhs& = a[i];
lhs = rhs;
// or
int lhs& = a[i];
int rhs = i++;
lhs = rhs;
Проверенная дважды блокировка. И одна легкая ошибка сделать.
A* a = new A("plop");
// Looks simple enough.
// But this can be split into three parts.
(a) allocate Memory
(b) Call constructor
(c) Assign value to 'a'
// No problem here:
// The compiler is allowed to do this:
(a) allocate Memory
(c) Assign value to 'a'
(b) Call constructor.
// This is because the whole thing is between two sequence points.
// So what is the big deal.
// Simple Double checked lock. (I know there are many other problems with this).
if (a == null) // (Point B)
{
Lock lock(mutex);
if (a == null)
{
a = new A("Plop"); // (Point A).
}
}
a->doStuff();
// Think of this situation.
// Thread 1: Reaches point A. Executes (a)(c)
// Thread 1: Is about to do (b) and gets unscheduled.
// Thread 2: Reaches point B. It can now skip the if block
// Remember (c) has been done thus 'a' is not NULL.
// But the memory has not been initialized.
// Thread 2 now executes doStuff() on an uninitialized variable.
// The solution to this problem is to move the assignment of 'a'
// To the other side of the sequence point.
if (a == null) // (Point B)
{
Lock lock(mutex);
if (a == null)
{
A* tmp = new A("Plop"); // (Point A).
a = tmp;
}
}
a->doStuff();
// Of course there are still other problems because of C++ support for
// threads. But hopefully these are addresses in the next standard.
Моим фаворитом является "Бесконечная рекурсия в инстанцировании шаблонов", потому что я полагаю, что это - единственное, где неопределенное поведение происходит во время компиляции.
Присвоение константе после разделения const
мыс с помощью const_cast<>
:
const int i = 10;
int *p = const_cast<int*>( &i );
*p = 1234; //Undefined
Кроме того неопределенное поведение , существует также одинаково противное определенное реализацией поведение .
Неопределенное поведение происходит, когда программа делает что-то, результат которого не определяется стандартом.
определенное Реализацией поведение является действием программой, результат которой не определяется стандартом, но который реализация требуется, чтобы документ. Примером являются "Литералы многобайтового символа", от вопроса о Переполнении стека там компилятор C, которому не удается скомпилировать это? .
определенное Реализацией поведение только кусает Вас, когда Вы начинаете портировать (но обновить до новой версии компилятора, также портирует!)
Переменные могут только быть обновлены однажды в выражении (технически однажды между точками последовательности).
int i =1;
i = ++i;
// Undefined. Assignment to 'i' twice in the same expression.
Единственный тип, для которого C++ гарантирует размер, char
. И размер равняется 1. Размер всех других типов является зависимым платформы.
Объекты уровня имен в разных единицах компиляции никогда не должны зависеть друг от друга при инициализации, так как порядок их инициализации не определен.
.