Каковы все общие неопределенные поведения, о которых должен знать программист на C++? [закрытый]

Неустранимая ошибка: вызов неопределенной функции XXX

Случается, когда вы пытаетесь вызвать функцию, которая еще не определена. Общие причины включают отсутствующие расширения и включают в себя объявление условной функции, функцию в объявлении функции или простые опечатки.

Пример 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, найдите информацию о том, почему, поскольку это может быть уже не нужно.

В случае отсутствия включено, обязательно включите файл, объявляющий функцию перед вызовом функции.

В случае опечаток исправить опечатку.

Вопросы, относящиеся

201
задан Peter Mortensen 22 January 2014 в 10:11
поделиться

9 ответов

Указатель

  • Разыменование NULL указатель
  • Разыменование указателя, возвращенного "новым" выделением нулевого размера
  • Используя указатели на объекты, время жизни которых закончилось (например, стек выделил объекты или удаленные объекты)
  • Разыменование указателя, который еще не был определенно инициализирован
  • Работающая адресная арифметика с указателями, которая приводит к результату вне границ (любой выше или ниже) массива.
  • Разыменование указателя в местоположении вне конца массива.
  • указатели Преобразования на объекты несовместимых типов
  • Используя memcpy для копирования перекрывающихся буферов .

Переполнение буфера

  • Чтение или запись в объект или массив при смещении, которое отрицательно, или вне размера того объекта (переполнение стека/"кучи")

Целочисленные переполнения

  • переполнение Целого числа со знаком
  • Оценка выражения, которое математически не определяется
  • лево-смещающиеся значения отрицательной суммой (сдвиги вправо отрицательными суммами являются определенной реализацией)
  • Смещающиеся значения суммой, больше, чем или равный числу битов в числе (например, int64_t i = 1; i <<= 72 не определено)

Типы, Бросок и Константа

  • Кастинг числового значения в значение, которое не может быть представлено целевым типом (или непосредственно или через static_cast)
  • Используя автоматическую переменную, прежде чем это было определенно присвоено (например, int i; i++; cout << i;)
  • Используя значение любого объекта типа кроме volatile или sig_atomic_t в получении сигнала
  • , Пытающегося изменить строковый литерал или любой другой объект константы в течение его времени жизни
  • Конкатенация узкого с широким строковым литералом во время предварительной обработки

Функция и Шаблон

  • Не возврат значения от возвращающей значение функции (непосредственно или путем течения прочь от блока попытки)
  • Несколько различных определений для того же объекта (класс, шаблон, перечисление, подставляемая функция, статическая функция членства, и т.д.)
  • Бесконечная рекурсия в инстанцировании шаблонов
  • Вызов функции с помощью различных параметров или связи с параметрами и связи, что функция определяется как использование.

ООП

  • Расположение каскадом destructions объектов со статической продолжительностью хранения
  • результат присвоения частично перекрывающимся объектам
  • Рекурсивно повторно введение функции во время инициализации ее статических объектов
  • звонки виртуальной функции Совершения к чистым виртуальным функциям объекта от ее конструктора или деструктора
  • что касается нестатических членов объектов, которые не были созданы или были уже разрушены

Исходный файл и Предварительная обработка

  • А непустой исходный файл, который не заканчивается новой строкой, или заканчиваются обратной косой чертой (до C++ 11)
  • обратная косая черта А, сопровождаемая символом, который не является частью указанных кодов Escape в символьной или строковой константе (это определяется реализацией в C++ 11).
  • Чрезмерные допустимые ограничения реализации (количество вложенных блоков, количество функций в программе, доступное стековое пространство...)
  • числовые значения Препроцессора, которые не могут быть представлены long int
  • директива Предварительной обработки по левой стороне подобного функции макроопределения
  • Динамично генерация определенного маркера в #if выражение

, которое будет классифицировано

  • выход Вызова во время разрушения программы со статической продолжительностью хранения
233
ответ дан 18 revs, 10 users 33% 23 November 2019 в 05:04
поделиться

Порядок, что параметры функции оценены, неуказанный поведение . (Это не заставит Вашу программу разрушить, взорвать или заказать пиццу..., в отличие от этого неопределенный поведение .)

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

<час>

Это:

// 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);

Это может быть также; это до компилятора. Результат может иметь значение, в зависимости от побочных эффектов.

31
ответ дан Mateen Ulhaq 23 November 2019 в 05:04
поделиться

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

От исходного вопроса:

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.
27
ответ дан Martin York 23 November 2019 в 05:04
поделиться

Моим фаворитом является "Бесконечная рекурсия в инстанцировании шаблонов", потому что я полагаю, что это - единственное, где неопределенное поведение происходит во время компиляции.

5
ответ дан Daniel Earwicker 23 November 2019 в 05:04
поделиться

Присвоение константе после разделения const мыс с помощью const_cast<>:

const int i = 10; 
int *p =  const_cast<int*>( &i );
*p = 1234; //Undefined
5
ответ дан Mechanical snail 23 November 2019 в 05:04
поделиться

Кроме того неопределенное поведение , существует также одинаково противное определенное реализацией поведение .

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

определенное Реализацией поведение является действием программой, результат которой не определяется стандартом, но который реализация требуется, чтобы документ. Примером являются "Литералы многобайтового символа", от вопроса о Переполнении стека там компилятор C, которому не удается скомпилировать это? .

определенное Реализацией поведение только кусает Вас, когда Вы начинаете портировать (но обновить до новой версии компилятора, также портирует!)

5
ответ дан Community 23 November 2019 в 05:04
поделиться

Переменные могут только быть обновлены однажды в выражении (технически однажды между точками последовательности).

int i =1;
i = ++i;

// Undefined. Assignment to 'i' twice in the same expression.
4
ответ дан Peter Mortensen 23 November 2019 в 05:04
поделиться

Единственный тип, для которого C++ гарантирует размер, char. И размер равняется 1. Размер всех других типов является зависимым платформы.

2
ответ дан Peter Mortensen 23 November 2019 в 05:04
поделиться

Объекты уровня имен в разных единицах компиляции никогда не должны зависеть друг от друга при инициализации, так как порядок их инициализации не определен.

.
2
ответ дан 23 November 2019 в 05:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: