Раздел: Документация / Стандарт языка С++ /

1.9. Выполнение программы

Все способы изучить Python Все способы изучить С++

Начинающие программисты даже не догадываются о том, какой огромный пласт в этой области скрыт от их глаз, и чего многие из новичков не увидят никогда, потому что это тёмная сторона программирования - чистый исходный код системного уровня… Подробнее...

1. Семантические описания в этом Международном Стандарте определяют параметризованную недетерминированную абстрактную машину. Этот Международный стандарт не предъявляет никаких требований к структуре соответствующих реализаций. В частности, им не нужно копировать или эмулировать структуру абстрактной машины. Скорее, соответствующие реализации требуются для эмуляции (только) наблюдаемого поведения абстрактной машины, как описано ниже.

ПРИМЕЧАНИЕ: Это положение иногда называют правилом “как если бы”, потому что реализация может игнорировать любое требование этого Международного стандарта до тех пор, пока результат будет таким, как если бы требование было выполнено, насколько это можно определить по наблюдаемому поведению программы. Например, фактической реализации не нужно оценивать часть выражения, если она может сделать вывод, что его значение не используется и что не возникает никаких побочных эффектов, влияющих на наблюдаемое поведение программы.

2. Некоторые аспекты и операции абстрактной машины описаны в этом Международном стандарте как определяемые реализацией (например, sizeof(int)). Они составляют параметры абстрактной машины. Каждая реализация должна включать документацию, описывающую ее характеристики и поведение в этих отношениях. Такая документация должна определять экземпляр абстрактной машины, соответствующий этой реализации (именуемый ниже “соответствующим экземпляром”).

ПРИМЕЧАНИЕ: Эта документация также включает в себя условно поддерживаемые конструкции и поведение, зависящее от локали. См. раздел 1.4.

3. Некоторые другие аспекты и операции абстрактной машины описаны в этом Международном стандарте как неуказанные (например, оценка выражений в новом инициализаторе, если функция выделения не выделяет память (5.3.4)). Там, где это возможно, этот Международный стандарт определяет набор допустимых моделей поведения. Они определяют недетерминированные аспекты абстрактной машины. Таким образом, экземпляр абстрактной машины может иметь более одного возможного выполнения для данной программы и данного ввода.

4. Некоторые другие операции описаны в этом Международном стандарте как неопределенные (например, итог попытки изменить объект const). [ Примечание: Этот Международный стандарт не предъявляет никаких требований к поведению программ, которые содержат неопределенное поведение. — конец примечания ]

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

6. Если обработчик сигнала выполняется в результате вызова функции raise, то выполнение обработчика выполняется последовательно после вызова функции raise и до ее завершения. [ Примечание: Когда сигнал принимается по другой причине, выполнение обработчика сигнала обычно не упорядочено по отношению к остальной части программы. — конец примечания ]

7. Экземпляр каждого объекта с автоматической продолжительностью хранения (3.7.3) связан с каждой записью в его блоке. Такой объект существует и сохраняет свое последнее сохраненное значение во время выполнения блока и во время приостановки блока (вызовом функции или получением сигнала).

8. Наименьшими требованиями к соответствующей реализации являются:

(8.1) — Доступ к изменчивым объектам оценивается строго в соответствии с правилами абстрактной машины.

(8.2) — При завершении программы все данные, записанные в файлы, должны быть идентичны одному из возможных результатов, которые дало бы выполнение программы в соответствии с абстрактной семантикой.

(8.3) — Динамика ввода и вывода интерактивных устройств должна осуществляться таким образом, чтобы вывод запроса фактически осуществлялся до того, когда программа ожидает ввода. То, что представляет собой интерактивное устройство, определяется реализацией.

В совокупности это называется наблюдаемым поведением программы. [ Примечание: Более строгие соответствия между абстрактной и фактической семантикой могут быть определены каждой реализацией. — конец примечания ]

9. [ Примечание: Операторы могут быть перегруппированы в соответствии с обычными математическими правилами только в тех случаях, когда операторы действительно являются ассоциативными или коммутативными (перегруженные операторы никогда не считаются ассоциативными или коммутативными). Например, в следующем фрагменте

int a, b;
/* ... */
a = a + 32760 + b + 5;

операторы выражения ведут себя точно так же, как

a = (((a + 32760) + b) + 5);

из-за ассоциативности и приоритета этих операторов. Таким образом, результат суммы (a + 32760) затем добавляется к b, а затем этот результат добавляется к 5, что приводит к значению, присвоенному a. На машине, в которой переполнения приводят к исключению и в которой диапазон значений, представляемых с помощью int, равен [-32768,+32767], реализация не может переписать это выражение как

a = ((a + b) + 32765);

поскольку, если бы значения для a и b были соответственно -32754 и -15, то сумма a + b привела бы к исключению, в то время как исходное выражение нет; и выражение также не может быть переписано как

a = ((a + 32765) + b);

или

a = (a + (b + 32765));

поскольку значения для a и b могли быть соответственно 4 и -8 или -17 и 12. Однако на машине, в которой переполнения не приводят к исключению и в которой результаты переполнений обратимы, вышеприведенный оператор выражения может быть переписан реализацией любым из вышеперечисленных способов, поскольку произойдет тот же результат. — конец примечания ]

10. Полное выражение - это выражение, которое не является подвыражением другого выражения. [ Примечание: в некоторых контекстах, таких как невычисляемые операнды, синтаксическое подвыражение считается полным выражением (пункт 5). - конец примечания ] Если языковая конструкция определена для создания неявного вызова функции, использование языковой конструкции считается выражением для целей этого определения. Вызов деструктора, сгенерированного в конце срока жизни объекта, отличного от временного объекта, является неявным полным выражением. Преобразования, применяемые к результату выражения для удовлетворения требований языковой конструкции, в которой появляется выражение, также считаются частью полного выражения.

[ Пример:

struct S 
{
  S(int i): I(i) { }
  int& v() { return I; }
  private:
  int I;
};
S s1(1);  // полное выражение - это вызов S::S(int)
S s2 = 2; // полное выражение - это вызов S::S(int)
void f() 
{
  if (S(3).v()) // полное выражение включает преобразования   
  // lvalue в rvalue и int в bool, выполняемые до удаления 
  // временного значения в конце полного выражения
  { }
}

конец примера ]

11. [ Примечание: Оценка полного выражения может включать оценку подвыражений, которые лексически не являются частью полного выражения. Например, считается, что подвыражения, участвующие в оценке аргументов по умолчанию (8.3.6), создаются в выражении, вызывающем функцию, а не в выражении, определяющем аргумент по умолчанию. — конец примечания ]

12. Доступ к объекту, обозначенному изменяемым (volatile) значением glvalue (3.10), изменение объекта, вызов функции ввода-вывода библиотеки или вызов функции, выполняющей любую из этих операций, - все это побочные эффекты, которые представляют собой изменения в состоянии среды выполнения. Оценка (вычисление) выражения (или подвыражения) в целом включает в себя как вычисления значений (включая определение идентичности объекта для оценки glvalue и извлечение значения, ранее присвоенного объекту для оценки prvalue), так и инициирование побочных эффектов (side effects). Когда возвращается вызов функции ввода-вывода библиотеки или оценивается доступ к изменяемому объекту, побочный эффект считается завершенным, даже если некоторые внешние действия, подразумеваемые вызовом (например, сам ввод-вывод) или изменяемым доступом, возможно, еще не завершены.

13. Последовательность, описанная ранее, представляет собой асимметричную, транзитивную, попарную связь между вычислениями (оценками), выполняемыми одним потоком (1.10), что приводит к частичному порядку между этими вычислениями. Учитывая любые две оценки A и B, если A последовательно выполняется до B, то выполнение A должно предшествовать выполнению B. Если A не упорядочен до B, а B не упорядочен до A, то A и B не упорядочены. [ Примечание: Выполнение несвязанных вычислений (оценок) может перекрываться. — конец примечания ] Оценки A и B неопределенно упорядочены, когда либо A упорядочен до B, либо B упорядочен до A, но не указано, какой именно. [ Примечание: вычисления с неопределенной последовательностью не могут перекрываться, но любое из них может быть выполнено первым. — конец примечания ]

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

15. За исключением отмеченных случаев, оценки операндов отдельных операторов и подвыражений отдельных выражений не упорядочены. [ Примечание: В выражении, которое вычисляется более одного раза во время выполнения программы, несвязанные и неопределенно последовательные оценки его подвыражений не обязательно должны выполняться последовательно в разных оценках. — конец примечания ] Вычисления значений операндов оператора упорядочиваются до вычисления значения результата оператора. Если побочный эффект для скалярного объекта не имеет последовательности по отношению к другому побочному эффекту для того же скалярного объекта или вычислению значения с использованием значения того же скалярного объекта, и они потенциально не являются параллельными (1.10), поведение не определено. [ Примечание: Следующий раздел налагает аналогичные, но более сложные ограничения на потенциально параллельные вычисления. — конец примечания ]

[ Пример:

void f(int, int);
void g(int i, int* v) 
{
  i = v[i++];        // поведение не определено
  i = 7, i++, i++;   // i превращается в 9
  i = i++ + 1;       // поведение не определено
  i = i + 1;         // значение i увеличивается
  f(i = -1, i = -1); // поведение не определено
}

конец примера ]

При вызове функции (независимо от того, является ли функция встроенной или нет) каждое вычисление значения и побочный эффект, связанные с любым выражением аргумента или с постфиксным выражением, обозначающим вызываемую функцию, упорядочиваются перед выполнением каждого выражения или оператора в теле вызываемой функции. [ Примечание: Вычисления значений и побочные эффекты, связанные с различными выражениями аргументов, не упорядочены. - конец примечания ] Каждое вычисление в вызывающей функции (включая другие вызовы функций), которое иным образом специально не упорядочено до или после выполнения тела вызываемой функции, неопределенно упорядочено в соответствии с выполнением вызываемой функции (другими словами, выполнение функций не чередуется друг с другом). Некоторые контексты в C++ вызывают оценку вызова функции, даже если в модуле трансляции не отображается соответствующий синтаксис вызова функции. [ Пример: Оценка нового выражения вызывает одну или несколько функций выделения памяти и конструктора; см. 5.3.4. В другом примере вызов функции преобразования (12.3.2) может возникать в контекстах, в которых синтаксис вызова функции не отображается. — конец примера ] Ограничения последовательности выполнения вызываемой функции (как описано выше) являются особенностями оцениваемых вызовов функций, независимо от синтаксиса выражения, которое вызывает функцию.


Как стать программистом 2.0 Как стать программистом 2.0

Эта книга для тех, кто хочет стать программистом. На самом деле хочет, а не просто мечтает. И хочет именно стать программистом с большой буквы, а не просто научиться кулебякать какие-то примитивные программки… Подробнее...
Инфо-МАСТЕР ®
Все права защищены ©
e-mail: mail@info-master.su

Яндекс.Метрика