Обновить
8
0
Лев Мельников@MarkGrin

Пользователь

Отправить сообщение
Если всё правильно, то форматирование плохое. Отступ намекает, что оператор принадлежит циклу, а если всё правильно, то это не так.
Да, есть. n4567 (3.8.4)
A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor...
При вызове деструктора завершается время жизни объекта. При завершении времени жизни объекта теряются все его данные. Компилятор для оптимизации выкидывает изменение данных, которые все равно потом теряются.

Для таких «затираний» есть специальные функции. К memset_s не может быть применена такая оптимизация, поэтому ей пользуются, когда нужно затереть пароль в памяти, после работы с ним.
Да, точно! Вы правы. В булевском случае компилятор может доказать: «или UB, или всегда true» и заменить на «всегда true». А в небулевом случае ничего доказать нельзя.

Если логика программы гарантирует, что в первых четырех элементах массива есть элемент равный аргументу при всех вызовах, то никакого UB не будет. Например:

int array[10] = {};
std::size_t size = 0;
std::cin >> size;
for (std::size_t i = 0; i < size; i++)
    std::cout << array[i] << "\n"; 

UB такой код или нет, зависит от пользователя.
И в случае с указателем, и в случае с массивом происходит UB. Причем в случае с массивом компилятор сам понимает, что есть UB и оптимизирует(всегда возвращает true). Интересно почему он не производит аналогичную оптимизацию(например, всегда возвращать 0) в случае:
if (table[i] == v) return i;

Скорее всего из-за того, что разработчики компилятора посчитали, что оптимизировать, используя UB возвращение булевого литерала из функции можно, а вот возвращение lvalue(не знаю, есть ли такое понятие в С) нельзя.

Другой момент: может ли компилятор доказать UB в случае с указателем? Если может, то почему не оптимизирует? Если не может, то и оптимизировать(в общем случае) возможности у него нет.

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

#include <iostream>
  
struct Electron{
    char digits[10];
    Electron () {
        for (int i = 0; i <= 9; i++)
            digits[i] = '0' + i;
    }
    ~Electron() {
        for (int i = 0; i <= 9; i++)
            digits[i] = 'x';
    }
};

int main () {
    char array[256];
    Electron* a = new(array) Electron;

    for (int i = 0; i < 10; i++)
        std::cout << array[i];
    std::cout << "\n";

    a->~Electron();

    for (int i = 0; i < 10; i++)
        std::cout << array[i];
    std::cout << "\n";

    return 0;
}

-O3:
0123456789
0123456789

-O0:
0123456789
xxxxxxxxxx

Стандарт с++ не гарантирует порядок символов английского алфавита в char. Поэтому, чтобы проверить является ли символ буквой нужно пользоваться стандартной функцией std::isalpha.
bool isBukva (char symbol)
{
    return std::isalpha(symbol);
}

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность