Пространства имён
Варианты
Действия

The as-if rule

Материал из cppreference.com
< cpp‎ | language

 
 
Язык С++
Общие темы
Управление программой
Операторы условного выполнения
Операторы повторения
Операторы перехода
Функции
объявление функции
объявление лямбда-функции
шаблон функции
спецификатор inline
спецификаторы исключений (устарело)
спецификатор noexcept (C++11)
Исключения
Пространства имён
объявление пространства имён
псевдонимы пространства имён
Типы
спецификатор decltype (C++11)
Спецификаторы
cv-спецификаторы
спецификаторы продолжительности хранения
спецификатор constexpr (C++11)
спецификатор auto (C++11)
спецификатор alignas (C++11)
Инициализация
Литералы
Выражения
Утилиты
Типы
typedef-объявление
объявление псевдонима типа (C++11)
атрибуты (C++11)
Приведения типов
неявные преобразования
const_cast-преобразование
static_cast-преобразование
dynamic_cast-преобразование
reinterpret_cast-преобразование
C-подобное и функциональное приведение типов
Выделение памяти
Классы
Особые свойства классовых функций
Специальные функции-члены
Шаблоны
шаблон класса
шаблон функции
специализация шаблона
упакованные параметры (C++11)
Разное
Ассемблерные вставки
 
Позволяет любых код преобразования, которые не меняют наблюдаемое поведение программы
Оригинал:
Allows any and all code transformations that do not change the observable behavior of the program
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.

Содержание

[править] Объяснение

C + + компилятор разрешено выполнять любые изменения в программу тех пор, пока остается в силе следующее:
Оригинал:
The C++ compiler is permitted to perform any changes to the program as long as the following remains true:
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
  • Доступ (чтение и запись) для летучих объектов происходит в том же порядке, как написано.
    Оригинал:
    Accesses (reads and writes) to the volatile objects occur in the same order as written.
    Текст был переведён автоматически используя Переводчик Google.
    Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
  • В завершение программы, данные, записанные на все файлы, точно так, как если бы программа была выполнена, как написано.
    Оригинал:
    At program termination, the data written to all files is exactly as if the program was executed as written.
    Текст был переведён автоматически используя Переводчик Google.
    Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
  • Все операции ввода и вывода происходят в том же порядке и с тем же содержанием, как если бы программа была выполнена, как написано.
    Оригинал:
    All input and output operations occur in the same order and with the same content as if the program was executed as written.
    Текст был переведён автоматически используя Переводчик Google.
    Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.

[править] Заметки

Поскольку компилятор (обычно) не в состоянии проанализировать код внешних библиотек определить, является ли оно или не выполняет I / O или летучих доступа сторонних библиотек призывает также не влияет на оптимизацию. Тем не менее, стандартные звонки библиотеки могут быть заменены другими вызовами, устранены или добавлены в программу в процессе оптимизации.
Оригинал:
Because the compiler is (usually) unable to analyze the code of an external library to determine whether it does or does not perform I/O or volatile access, third-party library calls also aren't affected by optimization. However, standard library calls may be replaced by other calls, eliminated, or added to the program during optimization.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Программы с неопределенным поведением, например, благодаря доступу к массиву из границ, изменение конструкции объекта, Оценка порядка нарушения и т.д., свободный от какой, если правила: они часто меняют наблюдаемое поведение, когда перекомпилировать с разными настройками оптимизации. Например, если тест на целое число переполнения опирается на результат, что переполнение, например, if(n+1 < n) abort();, it is removed entirely by some compilers, потому что подписан переполнение неопределенное поведение и оптимизатор имеет право предположить, что это никогда не случится и тест является излишним.
Оригинал:
Programs with undefined behavior, e.g. due to access to an array out of bounds, modification of a const object, Оценка порядка violations, etc, are free from the as-if rule: they often change observable behavior when recompiled with different optimization settings. For example, if a test for signed integer overflow relies on the result of that overflow, e.g. if(n+1 < n) abort();, it is removed entirely by some compilers because подписан переполнение неопределенное поведение and the optimizer is free to assume it never happens and the test is redundant.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.
Копировать элизии является единственным четко определенным исключением из, как правило, если.
Оригинал:
Копировать элизии is the only well-defined exception from the as-if rule.
Текст был переведён автоматически используя Переводчик Google.
Вы можете проверить и исправить перевод. Для инструкций щёлкните сюда.

[править] Пример

int& preinc(int& n) { return ++n; }
int add(int n, int m) { return n+m; }
 
// volatile input to prevent constant folding
volatile int input = 7;
 
// volatile output to make the result a visible side-effect
volatile int result;
 
int main()
{
    int n = input;
// using built-in operators would invoke undefined behavior
//    int m = ++n + ++n;
// but using functions makes sure the code executes as-if
// the functions were not overlapped
    int m = add(preinc(n), preinc(n));
    result = m;
}

Вывод:

# full code of the main() function as produced by the GCC compiler
# x86 (Intel) platform:
        movl    input(%rip), %eax   # eax = input
        leal    3(%rax,%rax), %eax  # eax = 3 + eax + eax
        movl    %eax, result(%rip)  # result = eax
        xorl    %eax, %eax          # eax = 0 (the return value of main())
        ret
 
# PowerPC (IBM) platform:
        lwz 9,LC..1(2)
        li 3,0          # r3 = 0 (the return value of main())
        lwz 11,0(9)     # r11 = input;
        slwi 11,11,1    # r11 = r11 << 1;
        addi 0,11,3     # r0 = r11 + 3;
        stw 0,4(9)      # result = r0;
        blr
 
# Sparc (Sun) platform:
        sethi   %hi(result), %g2
        sethi   %hi(input), %g1
        mov     0, %o0                 # o0 = 0 (the return value of main)
        ld      [%g1+%lo(input)], %g1  # g1 = input
        add     %g1, %g1, %g1          # g1 = g1 + g1
        add     %g1, 3, %g1            # g1 = 3 + g1
        st      %g1, [%g2+%lo(result)] # result = g1
        jmp     %o7+8
        nop
 
# in all cases, the side effects of preinc() were eliminated, and the
# entire main() function was reduced to the equivalent of result = 2*input + 3;

[править] См. также