| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Что дает const в описании функции (для многопоточ) |
| Автор: neosapient 8.11.2007, 16:15 | ||
Вот увидел в чужем коде класс с методом
Что дает для метода/функции эта приставка "const", и как соотноситься она с многопоточностью? |
| Автор: bsa 8.11.2007, 16:17 |
| это означает, что данный метод не меняет поля класса. |
| Автор: Daevaorn 8.11.2007, 16:18 |
const говорит о том что внутри метода поля объекта не будут изменяться. |
| Автор: Alek86 8.11.2007, 16:22 |
| то есть в двух потоках их можно использовать, если в классе не объявлены mutable переменные и они (функции) не используют глобальные переменные короче говоря, гарантий с ними никаких. если это был "хитрый" вопрос препода, то можешь его немного обломать |
| Автор: archimed7592 8.11.2007, 16:34 |
Гарантии есть, если константная ф-ция детерминирована |
| Автор: neosapient 8.11.2007, 16:41 |
| пожалуйста, говорите более простым языком ---------- про mutable точно не скажу но есть класс диспетчер (в единственном экземпляре), который хранит указатели на список. есть метод добавления и удаления элементов из списка и переход по списку. вот я встретил этот параметр и подумал - может каким то из моих функций присвоить "const " посмотрите пример Там метод Add вызывается из одного потока, а методы GetNext и DeleteThisAndGetNext вызываются в двух потоках паралельно |
| Автор: archimed7592 8.11.2007, 16:46 |
Детерминированная ф-ция - это та, результат работы которой зависит только от аргументов, ей переданных. Т.е. результат такой ф-ции не должен зависеть ни от ввода с клавиатуры, ни от глобальных переменных, ни от результата другой недетерминированной ф-ции. |
| Автор: Dims 9.11.2007, 03:25 |
| Надо помнить, что функция-член класса -- это обычная глобальная функция, которой в первом параметре передаётся указатель на объект класса и кладётся в переменную this. Просто синтаксис для функций-членов -- сокращённый. Поскольку перед всеми другими указателями можно ставить const, то и перед этим должно быть можно. Но как, если он нигде не упоминается в записи? Вот и придумали, что словечко const надо ставить перед телом функции, если это определение и перед точкой с запятой, если это описание. На многопоточность это никак не влияет. Эта фича работает на уровне компилятора, который выдаёт ошибки, если ты пытаешься изменить значение по адресу, который объявлен const. Ограничение легко обойти, как намеренно, так и случайно. |
| Автор: neosapient 9.11.2007, 10:29 |
| Спасибо, вопрос исчерпан |
| Автор: JackYF 9.11.2007, 13:24 | ||
Неверно. В обоих случаях const ставится после определения параметров функции. |
| Автор: archimed7592 9.11.2007, 13:38 | ||
Кто-нибудь когда-нибудь встречал что-нибудь вроде этого?
|
| Автор: Dims 9.11.2007, 23:02 | ||
Девятый вагон -- это тот который после восьмого, а не тот, который перед десятым |
| Автор: JackYF 9.11.2007, 23:26 | ||
Тьфу, да. Просто, имхо, как-то ты коряво написал, хотя, действительно, правильно нет :( |
| Автор: Alek86 10.11.2007, 11:20 |
| извиняюсь за продолжение темы. если спрашивалось что-то типа, могу ли я ее безбоязненно использовать в многих потоках, если вижу, что она const, то гарантий нету. статическая мьютэбл, вроде, возможна. |
| Автор: archimed7592 10.11.2007, 12:09 | ||
Если учесть, что константные ф-ции нехорошо делать недетерминированными, то да, можешь. |
| Автор: Alek86 10.11.2007, 12:29 |
| а mutable? он является чем-то плохим, что лучше не пользовать? |
| Автор: JackYF 10.11.2007, 13:45 |
опять же, почитай классиков. Его применять желательно только в обоснованных случаях, где без него не обойтись, в других случаях избегать. |
| Автор: archimed7592 10.11.2007, 13:58 |
Нет, с чего ты взял? |
| Автор: Alek86 10.11.2007, 16:16 | ||
в смысле, если я вижу константную функцию, то я НАДЕЮСЬ, что она не меняет статическую mutable (по сути, глобальную переменную). А гарантий никаких. В общем, вероятность подобного изврата край мала... |
| Автор: MAKCim 10.11.2007, 16:39 |
не встречал с трудом представляю, что оно может означать у меня есть только один вариант все поля в контексте volatile-метода являются volatile-полями, т. е их значения не кэшируются в регистрах при работе с ними так? |
| Автор: archimed7592 10.11.2007, 16:42 | ||
Вестимо, что так... Ну и, по аналогии, из такого метода не вызвать другие, менее cv-квалифицированные методы. Я вот только не приложу ума, как это можно использовать в реальной жизни |
| Автор: MAKCim 10.11.2007, 16:51 | ||
по аналогии с volatile для переменных метод вполне может вызываться извне (для одного и того же объекта) извне = другой поток или какое-либо асинхронное событие в основном потоке |
| Автор: JackYF 11.11.2007, 00:38 |
| MAKCim, итого - можно не ставить мутекс на чтение переменных, использующихся в методе. isn't it? |
| Автор: archimed7592 11.11.2007, 01:00 | ||
| volatile переменные очень редкое явление и используются исключительно для работы с аппаратурой и для реализации самых примитивных примитивов синхронизации Добавлено через 3 минуты и 9 секунд
Либо мьютексы можно было бы не ставить и без volatile, либо, volatile не поможет при работе без мьютексов |
| Автор: JackYF 11.11.2007, 02:51 |
| archimed7592, ключевое слово в фразе было - "на чтение" |
| Автор: archimed7592 11.11.2007, 03:08 | ||
| JackYF, ещё раз: либо читать можно без мьютекса - т.е. есть гарантии, что во время чтения не будет произведена запись. Такая гарантия есть, либо, когда происходит атомарная операция чтения(к примеру, чтение long long на x86 не является атомарной операцией), либо когда нет других потоков, работающих с переменной на запись. либо, если нужен мьютекс, volatile не поможет. Т.е. в данном случае:
метод и так может быть вызван(без его volatile-квалификации), а остальное зависит от логики работы этого метода(см. выше). volatile даёт только одну гарантию: компилятор не может переставлять местами обращение к volatile переменным(даже чтение). К примеру есть два порта, mapped to address space и представленные volatile переменными. Допустим тебе нужно отправить в первый порт какую-нибудь управляющую команду, а потом прочитать из второго порта результат. Компилятор гарантирует, что он не всунет чтение из второго порта перед записью в первый. Если ты уберёшь volatile-квалификацию, то с точки зрения компилятора, запись в одну переменную и чтение из другой - совершенно независимые операции и вполне сможет переставить их местами, ибо observable behaviour из-за этого не изменится. К слову, я не утверждаю "уберите нафик из стандарта возможность volatile-квалификации методов" |
| Автор: MAKCim 11.11.2007, 10:29 | ||
без мьютексов и прочих вещей это так, к слову вообще я с тобой согласен |
| Автор: MAKCim 11.11.2007, 11:04 | ||||
ты же сам привел пример вот реализация
|
| Автор: archimed7592 11.11.2007, 11:37 |
Ну этот пример немного из пальца ;). Присутствуют только volatile-квалифицированные данные и они просто не могут быть не volatile. К примеру, если у меня в классе есть поле, которое по идее меняться не должно, я из "стилевых" соображений сделаю это поле const вне зависимости от квалификации метода. По аналогии: здесь тоже я бы сразу поставил volatile на массив. Хотя... Какой-то смысл я в volatile-квалификации мьютекса начинаю видеть |
| Автор: JackYF 11.11.2007, 12:23 |
| archimed7592, угу, да, понял. |
| Автор: MAKCim 11.11.2007, 12:39 | ||
а зачем тут volatile на весь массив, если по сути volatile-поведение нужно только для одного метода? |
| Автор: archimed7592 11.11.2007, 16:20 | ||
А для остальных не нужно? |
| Автор: MAKCim 11.11.2007, 16:31 |
нет пример был не с потолка, а вполне реальный, для работы с I/O APIC некоторые регистры отображены на физическое адресное пространство напрямую а некоторые доступны косвенно через IO_APIC_DATA |