Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
1 / 1 / 0
Регистрация: 03.08.2017
Сообщений: 205

Имеет ли смысл создавать volatile переменную

16.09.2026, 11:08. Показов 13507. Ответов 171

Студворк — интернет-сервис помощи студентам
У меня есть функция
C++
1
2
void getParam(double &param){ //...
}
Вызов написал в таком виде:
C++
1
2
3
//...
{volatile double gain;
getParam((double&)gain);//...
Имеет ли смысл такая конструкция или лучше воспользоваться обычной переменной double?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.09.2026, 11:08
Ответы с готовыми решениями:

1 класс имеет переменную указатель на 2, 2 имеет на 1
Имеется 2 класса. В 1 классе есть переменная-указатель на 2 класс, а во 2 классе есть...

Применение описателя Volatile
Приведите плз пример простой проги с этим описателем а то я не пойму для чего он вообще нужен?В чём...

Пример использования спецификатора volatile
В приложенной картинке (из книги Г.С. Шилдта по C++) есть пример использования спецификатора...

171
274 / 206 / 30
Регистрация: 26.11.2022
Сообщений: 903
20.09.2026, 01:43
Студворк — интернет-сервис помощи студентам
volatile так легко объяснить - эта штука появилась тогда когда оптимизирующие компиляторы стали мешать написанию драйверов устройств. если программа пару раз записывала в одну и ту же область памяти заранее известные значения - это не от того что програмист глупый а потому что этому одресу в памяти соответствовало физическое устройство и последовательная запись данных по одному и тому же адресу была частью протокола по обмену данными с этим устройством.
так и появилось volatile - что если указано что то прочитать или записать в такую переменную (а чаще по указателю на область памяти)- то компилятору об этом явно сообщают - что эта память особенная.

ни к прерываниям ни к многопоточности это не имеет отношения. но некоторые особенности из такого поведения компиляторов пытаются использовать и для других целей.
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
20.09.2026, 02:45
Цитата Сообщение от Aledveu Посмотреть сообщение
ни к прерываниям ни к многопоточности это не имеет отношения.
Имеет. И к прерываниям и к многопоточности. Подумайте что будет, если оптимизирующий компилятор создаст копию переменной. Например в регистре. И будет с ней работать.
0
фрилансер
 Аватар для Алексей1153
6506 / 5755 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
20.09.2026, 08:36
Цитата Сообщение от jcxz Посмотреть сообщение
что будет, если оптимизирующий компилятор создаст копию переменной. Например в регистре.
это регулярно происходит, на это volatile не влияет.

например, Intel напрямую с памятью арифметические операции не производит, он почти всё делает через eax
https://godbolt.org/z/ne35hjx5a

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
volatile int N1;
volatile int N2;
volatile int N3;
 
int main()
{
    N1 = 42;
 
    N3 = N2 + N1;
 
    return N3;
}
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        .globl std::ios_base_library_init()
"main":
        mov     DWORD PTR "N1"[rip], 42
        mov     eax, DWORD PTR "N2"[rip]
        add     eax, DWORD PTR "N1"[rip]
        mov     DWORD PTR "N3"[rip], eax
        mov     eax, DWORD PTR "N3"[rip]
        ret
"N3":
        .zero   4
"N2":
        .zero   4
"N1":
        .zero   4
именно поэтому всё равно нужна атомарность или мьютекс при многопоточном доступе

ЗЫ оптимизация включена: -O3
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
20.09.2026, 08:45
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это регулярно происходит, на это volatile не влияет.
Что значит "не влияет"? Ваш пример как раз таки и демонстрирует то, что каждая операция чтения или записи значений переменных сопровождается чтением или записью значения в память, даже в режиме -O3. То есть ни полной замены памяти регистром, ни хоть сколь-нибудь продолжительного "кэширования" памяти в регистр не происходит. Именно это имел в виду jcxz. Именно об это идет речь в моем посте #19.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
он почти всё делает через eax
То, что все операции выполняются через посредство регистра - так это уже просто потому, что на платформе x86 нет подходящих операций формата "память - память" или "непосредственный операнд - память". Но речь-то шла не об этом.
0
фрилансер
 Аватар для Алексей1153
6506 / 5755 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
20.09.2026, 08:55
TheCalligrapher, речь у него идёт о том, что он желает заменить межпоточную синхронизацию через volatile

Но почему-то никто так не поступает
0
Модератор
Эксперт Java
 Аватар для alecss131
2902 / 1407 / 413
Регистрация: 11.08.2017
Сообщений: 4,512
Записей в блоге: 2
20.09.2026, 11:17
Грубо говоря volatile не решает проблему с race condition, а это ub в многопотоке.
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
20.09.2026, 11:58
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это регулярно происходит, на это volatile не влияет.
например, Intel напрямую с памятью арифметические операции не производит, он почти всё делает через eax
https://godbolt.org/z/ne35hjx5a
Попробуйте хоть на секунду включить голову и посмотреть на свой же код. Ваш код как раз и демонстрирует, что volatile влияет и благодаря ему копии переменных в регистрах не создаются. О чём я и писал.
Если бы не влиял, то 3-й командой была бы: add eax, 42 как более оптимальная; а 5-й команды и вовсе не было бы.
"Смотрю в книгу, вижу фигу" - это про вас. Вам компилятор даже в этом примере ясно показывает влияние volatile. Прямо в глаза тычет. Но вы этого в упор не видите и продолжаете нести чушь.
Цитата Сообщение от Алексей1153 Посмотреть сообщение
именно поэтому всё равно нужна атомарность или мьютекс при многопоточном доступе
У вас в голове каша из мух и котлет. Атомарность никак не отменяет необходимости volatile. Она никак не относится в нужности volatile. Атомарность - это вообще про другое. Атомарность - это неразрывность операций чтения-модификации-записи переменной с точки зрения стороннего контекста исполнения. С какого боку вы её приплели к volatile???
"Слышал звон, да не знаю где он". Опять про вас. Моя бабушка лучше разбирается в многопоточном программировании.

Добавлено через 2 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
То есть ни полной замены памяти регистром, ни хоть сколь-нибудь продолжительного "кэширования" памяти в регистр не происходит. Именно это имел в виду jcxz.
Именно так. Вы совершенно правы.

Добавлено через 5 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
То, что все операции выполняются через посредство регистра - так это уже просто потому, что на платформе x86 нет подходящих операций формата "память - память" или "непосредственный операнд - память". Но речь-то шла не об этом.
Тут вы не правы - такие операции в x86-архитектуре есть. Эти операции не используются именно из-за volatile у всех переменных. Уберите volatile - и скорей всего они будут использованы.
RMW-операций с памятью нет в ARM-архитектуре (за исключением опционального bitband). Но это никак не мешает реализации атомарности на ARM. Если у реализатора есть голова на плечах. Атомарность - это совсем про другое. Но чайники часто путаются. Что мы и видим в этой теме.

Добавлено через 2 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
TheCalligrapher, речь у него идёт о том, что он желает заменить межпоточную синхронизацию через volatile
Ложь!
Ни про какую "многопоточную синхронизацию" автор ни разу не упомянул. Он так и не сказал зачем ему всё это нужно. Хоть его и спрашивали.

Добавлено через 6 минут
Цитата Сообщение от alecss131 Посмотреть сообщение
Грубо говоря volatile не решает проблему с race condition, а это ub в многопотоке.
Опять валим с больной головы на здоровую. Причём тут "гонки"?

Объявление переменной volatile может быть вполне достаточно для некоторых способов межпоточной синхронизации. И позволяет обойтись без Interlocked-операций (на x86) или без операций эксклюзивного доступа (LDREX/STREX) на ARM и уж тем более - без мьютексов (с чего их сюда приплели - вообще неясно. Из контекста вопроса ТС даже не понятно - есть ли у него какие-то потоки или нет? Может у него однопоточный код с обработчиками прерываний и необходима корректная работа с переменной фонового кода и кода ISR)?
Это уже не говоря о том, что мьютексы - это блокирующее средство синхронизации. Т.е. - весьма тяжёлое. Не на всех платформах полностью корректно реализованное. И грамотный разработчик не должен использовать его там, где не требуется.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,217
Записей в блоге: 2
20.09.2026, 13:51
Цитата Сообщение от jcxz Посмотреть сообщение
Моя бабушка лучше разбирается в многопоточном программировании

Не по теме:

Так Вы совсем еще молодой парень если бабушка жива, дай бог ей здоровья

В перепалке все прямо блещут познаниями и эрудицией, но если можно поговорить о том же спокойно, нормально - молчок. Неужели обязательно нужно "переходить на личности" - это типа "источник вдохновения"? Пара примеров

В этой теме (пост #57) всем предлагалось покритиковать многопоточную реализацию простой задачи. Приходите, критикуйте, можно вместе с бабушкой
Цитата Сообщение от alecss131 Посмотреть сообщение
Грубо говоря volatile не решает проблему с race condition, а это ub в многопотоке.
Вот тема, пожалуйста, рассказывайте о проблеме, там об этом и разговор
0
фрилансер
 Аватар для Алексей1153
6506 / 5755 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
20.09.2026, 15:06
jcxz, вот тебе пример, что volatile не защищает от гонки данных

https://onlinegdb.com/fork/VaxQuPhPC
https://onlinegdb.com/fork/-c_36iGgv


переменная N должна остаться равной 0
volatile не помогает
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//-pedantic-errors -O3
#include <iostream>
#include <thread>
 
//переменная N должна остаться равной 0
 
//volatile не помогает
 
int main()
{
    constexpr size_t steps=1000000;
    
    volatile size_t N{};
 
    std::thread t1([&N]
    {
        for(size_t i=0; i<steps; ++i)
        {
            N++;
            N++;
            N++;
        }
    });
    
    std::thread t2([&N]
    {
        for(size_t i=0; i<steps; ++i)
        {
            N--;
            N--;
            N--;
        }
    });
    
    t1.join();
    t2.join();
    
    std::cout<<"N=" << N;
}

атомарная переменная N должна остаться равной 0
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//-pedantic-errors -O3
#include <iostream>
#include <thread>
#include <atomic>
 
//атомарная переменная N должна остаться равной 0
 
int main()
{
    constexpr size_t steps=1000000;
    
    std::atomic<size_t> N{};
 
    std::thread t1([&N]
    {
        for(size_t i=0; i<steps; ++i)
        {
            N++;
            N++;
            N++;
        }
    });
    
    std::thread t2([&N]
    {
        for(size_t i=0; i<steps; ++i)
        {
            N--;
            N--;
            N--;
        }
    });
    
    t1.join();
    t2.join();
    
    std::cout<<"N=" << N;
}
0
 Аватар для volodin661
7153 / 2341 / 353
Регистрация: 10.12.2013
Сообщений: 8,122
20.09.2026, 15:07
"Моя бабушка лучше разбирается в многопоточном программировании"

2026год.
безоглядно кидаться бабушками и дедушками при аргументации в части обсуждения многопоточного программирования не стоит. К примеру, дедушка Катлер, 86 лет, автор ядра Windows NT ( ну и VMS заодно ) весьма неплох в многопоточном программировании.
0
274 / 206 / 30
Регистрация: 26.11.2022
Сообщений: 903
20.09.2026, 15:48
Похоже многие путают volatile, атомарный доступ к памяти и атомарную операцию с содержимым памяти.
Отсюда и брожение умов.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
20.09.2026, 16:29
Цитата Сообщение от jcxz Посмотреть сообщение
Тут вы не правы - такие операции в x86-архитектуре есть.
Это какие, интересно?

Да, если задаться сумасшедшей целью, то выполнить непосредственное присваивание "память - память" переменных типа int на платформе x86, разумеется, можно через инструкцию movsb. Но никакого смысла в таком извращении нет и "подходящим" такой вариант называть не приходится.

Еще какие-то?
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,217
Записей в блоге: 2
20.09.2026, 16:37
Цитата Сообщение от jcxz Посмотреть сообщение
да уж... пациент безнадёжен...
Не вижу оснований для иронии. Пример Алексей1153 пусть прост, но совершенно разумен и понятен
Цитата Сообщение от jcxz Посмотреть сообщение
Видна разница между переменными с volatile и без оных. И из него видна польза от volatile для многопоточной синхронизации. Кто умеет думать, тот всё поймёт из этого кода. Остальные - проходим мимо. За букварём.
Разница в коде действительно видна. А вот "польза от volatile для многопоточной синхронизации" - как-то не очень. И не надо "брать на понт", мол, да это все знают. Приведите пример такой пользы
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
20.09.2026, 16:44
... отдельно стоит заметить, что в теме конкурентного исполнения кода синхронизация и атомарность доступа - это совершенно разные вещи. Тут, я смотрю, оба термина валятся в одну кучу и используются как фактические синонимы, что является полнейшим бредом.
0
 Аватар для Recrut_rf
391 / 336 / 66
Регистрация: 14.10.2014
Сообщений: 1,537
20.09.2026, 17:19
jykm, если предстоит работать с железом - то очень даже имеет. Прям must have в некоторых случаях. Сам видел и даже немного работал с кодом, где volatile во всю использовался.
0
фрилансер
 Аватар для Алексей1153
6506 / 5755 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
20.09.2026, 17:25
Цитата Сообщение от jcxz Посмотреть сообщение
если речь идёт о volatile
Цитата Сообщение от jcxz Посмотреть сообщение
Объявление переменной volatile может быть вполне достаточно для некоторых способов межпоточной синхронизации.


jcxz, я сейчас именно про это.

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

Но причин для хамства не вижу . Даже от тех, кто элементарно не умеет расшаривать ссылку. Внутри которой некомпилирующийся однопоточный код
0
274 / 206 / 30
Регистрация: 26.11.2022
Сообщений: 903
20.09.2026, 18:18
была где-то научная статься о том что достаточно для межпоточной синхронизации.
и вывод там был такой что необходимо и достаточно иметь инструкцию "atomic compare exchange"
всё остальное не даёт гарантий.
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
20.09.2026, 19:07
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это какие, интересно?
На x86 есть множество команд типа: память-непосредственный операнд.
Типа: ADD [EDI],5 и других подобных. См.систему команд x86.

Добавлено через 3 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Пример Алексей1153 пусть прост, но совершенно разумен и понятен
Вы тоже не читатель а писатель?
Ещё раз и для вас: При чём тут атомарность и гонки если речь идёт о volatile? Какое отношение к теме имеет пример о неких гонках, если речь про volatile?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
20.09.2026, 19:14
Цитата Сообщение от Алексей1153 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
    std::thread t1([&N]
    {
        for(size_t i=0; i<steps; ++i)
        {
            N++;
            N++;
            N++;
        }
    });
Кстати, занимательный вопрос на отвлеченную тему: при использовании std::atomic<> доступ через захваченную ссылку сопровождается усердным перевычитыванием значения ссылки перед каждым инкрементом в цикле

Assembler
1
2
3
4
5
     mov rdx, QWORD PTR [rdi+8] ; чтение значения ссылки
lock add QWORD PTR [rdx], 1
     mov rdx, QWORD PTR [rdi+8] ; снова чтение значения ссылки?
lock add QWORD PTR [rdx], 1
     ...
а вариант с volatile перечитыванием значения ссылки не занимается, то есть перед циклом один раз делается

Assembler
1
mov rax, QWORD PTR [rdi+8] ; чтение значения ссылки один раз
а затем в цикле

Assembler
1
2
3
4
mov rdx, QWORD PTR [rax] ; в цикле полагается, что значение `rax` стабильно
add rdx, 1
mov QWORD PTR [rax], rdx
...
Вышеприведенное - это GCC. Clang в первом варианте - то же самое, а во втором варианте почти то же самое (для инкремента использует inc). То есть что касается вопроса перевычитывания ссылки - Clang проявляет то же странное поведение, что и GCC.

Почему? Зачем все время перечитывать значение ссылки в цикле в первом варианте? Просто косяк оптимизатора-кодогенератора? Или я упускаю какие-то более веские причины?
0
352 / 150 / 10
Регистрация: 19.07.2024
Сообщений: 842
20.09.2026, 19:22
Цитата Сообщение от Igor3D Посмотреть сообщение
И не надо "брать на понт", мол, да это все знают. Приведите пример такой пользы
Синхронизация 2-х потоков на базе volatile-переменных:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
int volatile state = 0;
 
void Act1() {...}
void Act2() {...}
void Act3() {...}
void Act4() {...}
void Sleep();  //уйти в сон или отдать время системе если для потока нет работы
void Ping();   //пнуть чужой поток если перекинули мяч на его сторону поля (опционально)
 
void Task1()
{
  int i;
  for (;;) {
    while ((i = state) & 1) Sleep();
    switch (i) {
      case 0:
        Act1();
        break;
      case 2:
        Act3();
        break;
    }
    state = i + 1;
    Ping();
  }
}
 
void Task2()
{
  int i;
  for (;;) {
    while (!((i = state) & 1)) Sleep();
    switch (i) {
      case 1:
        Act2();
        break;
      case 3:
        Act4();
        break;
    }
    state = i + 1 & 3;
    Ping();
  }
}
Нормально работает на любой платформе имеющей атомарные операции чтения и записи для типа int (x86, ARM, etc.). Потоки могут выполняться даже на разных ядрах - тоже всё ок. Без всяких мьютексов и т.п.

Добавлено через 3 минуты
Цитата Сообщение от Aledveu Посмотреть сообщение
была где-то научная статься о том что достаточно для межпоточной синхронизации.
и вывод там был такой что необходимо и достаточно иметь инструкцию "atomic compare exchange"
всё остальное не даёт гарантий.
Изучите пример, что я привёл. Он не требует "atomic compare exchange" и нормально работает. Даже если потоки на разных ядрах.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.09.2026, 19:22

const volatile
Пример из Шилдт Г. &quot;С++ Базовый курс (3-е издание, 2010)&quot; стр 205 const volatile unsigned char...

исследование volatile
Здравствуйте. В университете дали задание: &quot;Исследование квалификаторов volatile и инструкции...

int\ volatile int \ const int
Товарищи, паника! Имеется код: int a = 5; std::cout &lt;&lt; &quot;Init value a: &quot; &lt;&lt; a &lt;&lt; &quot;\n&quot;; ...

const_cast: const и volatile
Как известно const_cast сбрасывает наложенные ограничения при помощи модификаторов const и...

Что такое "volatile int"
есть объявление и инициализация переменной: volatile int Sklad = 0; что такое &quot;volatile&quot;? с msdn...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru