LINUX.ORG.RU

const и volatile

 ,


0

2

Находил для себя на киберфоруме небольшую памятку про const

/* Переменную нельзя модифицировать */
int const a;
 
/* Эквивалентно "int const a;" */
const int a;
 
/* Указатель модифицировать (a = ...) можно, но записывать
 * по указателю (*a = ...) нельзя */
const int *a;
 
/* Эквивалентно "const int *a;" */
int const *a;
 
/* Указатель модифицировать (a = ...) нельзя, но записывать
 * по указателю (*a = ...) можно */
int * const a;
 
/* Указатель модифицировать (a = ...) нельзя, записывать
 * по указателю (*a = ...) нельзя */
const int * const a;

Справедливо ли всё это для volatile?

★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)

проверь да расскажи нам, тоже мне, лор

anonymous
()

открыть стандарт так тяжело

anonymous
()

Справедливо ли всё это для volatile?

нет. volatile вообще имеет совершенно иной смысл, нежели const.

const применяется во время компиляции, и если ты в коде явно меняешь const, то компилятор отказывается это собирать. В рантайме никаких const нет, это просто фича компилятора, что-бы НЕ компилировать говнокод, в котором константы меняются. Также явный и неявный const используется во время оптимизации, например если функция получает указатель на константную ссылку, компилятор может не разыменовывать эту ссылку ещё раз, т.к. знает, что значение по константной ссылке не меняется. Конечно ты его можешь поменять static_cast'ом, и получить UB в репу.

volatile наоборот, работает в рантайме. Компилятор volatile использует для того, что-бы наоборот, постоянно разыменовывать ссылки, когда надо, и когда не надо, ибо они _могут_ ВНЕЗАПНО измениться.

А синтаксически они да, вроде одинаково пишутся. Но за кой ляд ты их к указателям применяешь — я теряюсь в догадках.

emulek
()
Ответ на: комментарий от emulek

Но за кой ляд ты их к указателям применяешь — я теряюсь в догадках.

За тем же, зачем и к всему остальному – объявить, что указатель меняться не будет.

Stil ★★★★★
()
Ответ на: комментарий от emulek

volatile наоборот, работает в рантайме. Компилятор volatile использует для того, что-бы наоборот, постоянно разыменовывать ссылки, когда надо, и когда не надо, ибо они _могут_ ВНЕЗАПНО измениться.

Так всё равно же код, который это делает, генерируется именно на этапе компиляции. Чем это отличается от

Также явный и неявный const используется во время оптимизации, например если функция получает указатель на константную ссылку, компилятор может не разыменовывать эту ссылку ещё раз, т.к. знает, что значение по константной ссылке не меняется.

?

asaw ★★★★★
()
Ответ на: комментарий от Stil

Но за кой ляд ты их к указателям применяешь — я теряюсь в догадках.

За тем же, зачем и к всему остальному – объявить, что указатель меняться не будет.

речь о volatile

emulek
()
Ответ на: комментарий от asaw

Так всё равно же код, который это делает, генерируется именно на этапе компиляции. Чем это отличается от

оптимизация const это дополнительная фича const. Основное изначальное назначение: отделить const методы и аргументы от не-const. В частности, что-бы использовать метод как l-value. А потом уже const оказался нужен и годен, и его ввели и в ansi C.

emulek
()

я познаю мир

Тебе никогда не понадобится volatile.

Справедливо ли всё это для volatile?

Да.

mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

Тебе никогда не понадобится volatile.

Может и понадобиться на каком-нибудь собеседовании, когда какой-нибудь очередной дрочер решит задать подобный вопрос.

asaw ★★★★★
()
Последнее исправление: asaw (всего исправлений: 1)
Ответ на: комментарий от emulek

+ на сколько я знаю, volatile говорит компилятору не оптимизировать переменную, например

{
    volatile unsigned long *LPCI_4C = (unsigned long *) (dev->core.lin_base[0] + 0x4C);
    *LPCI_4C |= 0x49;

/*    while (*LPCI_4C & 0x24 == 0);    */
    if (wait_event_interruptible(dev->wq, *LPCI_4C & 0x24))
        return -ERESTARTSYS;

    *LPCI_4C &= ~0x40;
}
по-идее, компилятор может выкинуть обращения к этой переменной, а нельзя - LPCI_4C железкой управляет.

metawishmaster ★★★★★
()
Последнее исправление: metawishmaster (всего исправлений: 1)
Ответ на: комментарий от asaw

Может и понадобиться на каком-нибудь собеседовании

в принципе — да.

emulek
()

http://www.barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword

A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:

1. Memory-mapped peripheral registers

2. Global variables modified by an interrupt service routine

3. Global variables accessed by multiple tasks within a multi-threaded application

Я бы ещё отдельным пунктом вынес сигналы. Wikipedia также упомянает setjmp/longjmp.

runtime ★★★★
()
Последнее исправление: runtime (всего исправлений: 1)

Палю легко запоминающуюся годноту:

const относится к тому, что написано слева от него, но если const это самая левая штука, то тогда const относится к тому, к чему ближе всего.

hlebushek ★★
()

Справедливо ли всё это для volatile?

Да.

Pavval ★★★★★
()
Ответ на: комментарий от mix_mix

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

Спасибо всем, за то, что внесли ясность.

WRG ★★★★
() автор топика
Последнее исправление: WRG (всего исправлений: 1)
Ответ на: комментарий от emulek

В рантайме никаких const нет

В рантайме дохрена const, если, как в тех же микроконтроллерах, есть ПЗУ или флэш — в общем, память, немодифицируемая в рантайме. Тогда константы будут лежать в ней вместе с исполняемым кодом и не будут занимать место в ОЗУ, которое может быть ограничено.

alegz ★★★★
()
Ответ на: комментарий от WRG

Он мне всё таки понадобился, ибо я программирую микроконтроллер

А, ну это другое дело.

mix_mix ★★★★★
()
Ответ на: комментарий от fluorite

За микроконтроллеры особо не знаю, но ты уверен, что тебе нужен volatile

Да.

mix_mix ★★★★★
()
Ответ на: комментарий от unt1tled

const лежит в .const, естественно. А вот .const может лежать во флэш/ПЗУ, там же, где и .text.

Хотя иногда константы с адресами могут и не создаваться, а их значения просто зафигачиваться непосредственно в код, а ля #define. От оптимизатора зависит.

(На самом деле продвинутые компиляторы позволяют хоть каждую отдельную переменную в собственную секцию засунуть, а эту секцию — куда угодно в памяти.)

alegz ★★★★
()
Последнее исправление: alegz (всего исправлений: 1)
Ответ на: комментарий от unt1tled

а почему бы им там и не лежать. На некоторых архитектурах типично для констант так сказать ближнего доступа. Пример

int kfix(int input, int lfix) {
	const int lkey = 0x87654321;
        return input * lfix + lkey;
}

Имеем на ARM-е:

	.text
	.align	2
	.global	kfix
	.type	kfix, %function
kfix:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	ldr	r3, .L2
	mla	r0, r1, r0, r3
	bx	lr
.L3:
	.align	2
.L2:
	.word	-2023406815
	.size	kfix, .-kfix

-2023406815 очень напоминает 0x87654321

io ★★
()
Ответ на: комментарий от WRG

Он мне всё таки понадобился, ибо я программирую микроконтроллер

там надо иногда. Я вспомнил: где-то в интернетах кто-то когда-то пустил слух, что volatile это, якобы, противоположность const. Но это не так.

На самом деле, volatile это противоположность register. Когда переменную описываешь как register, компилятор старается засунуть в регистр, иначе, при volatile — не засовывает никогда, держит в памяти, иначе «без никто» или с auto — на усмотрение компилятора.

Ну а const в стандарте C вообще не было раньше.

emulek
()
Ответ на: комментарий от alegz

В рантайме дохрена const, если, как в тех же микроконтроллерах, есть ПЗУ или флэш

если число лежит в ПЗУ, то его хоть с const, хоть без, всё равно хрен запишешь.

emulek
()
Ответ на: комментарий от unt1tled

можно подробней, как const может лежать в .text сегменте?

да легко, вот например константа 0x9 в .text

 8048380:   80 f9 09                cmp    cl,0x9

emulek
()
Ответ на: комментарий от emulek

что volatile это, якобы, противоположность const. Но это не так.

В стандарте есть очень няшный пример:

extern const volatile int real_time_clock;

На самом деле, volatile это противоположность register.

Оно вообще ничему не «противоположность», оно само по себе. А на register уж сто лет как оптимизаторы обращают внимание в последнюю очередь.

Ну а const в стандарте C вообще не было раньше.

«Раньше» — это во времена K&R, что ли? В ANSI C 1989 года точно было.

alegz ★★★★
()
Ответ на: комментарий от emulek

если число лежит в ПЗУ, то его хоть с const, хоть без, всё равно хрен запишешь.

Так чтобы оно туда попало, его и надо объявить как const. Ну, или шаманить с секциями, директивами линкера и прочей магией.

alegz ★★★★
()
Ответ на: комментарий от emulek

Я вспомнил: где-то в интернетах кто-то когда-то пустил слух, что volatile это, якобы, противоположность const. Но это не так.

Это вопрос из области лингвистики а не программирования.

const int* p

значение по адресу p не может быть изменено

volatile int* p

значение по адресу p может быть изменено в любой момент

Соответственно на эти два случая можно смотреть как на две крайности, что позволяет применять к ним термин «противоположность».

К физическому смыслу const/volatile и к их определению в стандарте это имеет весьма посредственное отношение. const/volatile означают то что они означают. nothing more, nothing less.

anonymous
()
Ответ на: комментарий от anonymous

Соответственно на эти два случая можно смотреть как на две крайности, что позволяет применять к ним термин «противоположность».

историю тоже необходимо учитывать. Раньше в сишке вообще const не было, да и сегодня полно кода без const.

А вот volatile/registr раньше в полный рост использовали, т.к. компиляторы были слишком примитивные, и нуждались в подсказках.

emulek
()
Ответ на: комментарий от anonymous

Можно быть const volatile

конечно может, почему нет?

emulek
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.