Необходимость/желательность volatile
От: emusic Франция https://software.muzychenko.net/ru
Дата: 19.01.05 12:30
Оценка: +1
Здравствуйте, MaximE, Вы писали:

ME>Компилятор должен поддерживать многопоточность — это раз.


Из чего следует, что компилятор должен ее поддерживать своими силами? Компилятор предоставляет средства для отражения многопоточного характера кода. Пользоваться этими средствами или нет — выбор программиста.

ME>Семантика volatile — implementation defined — это два.


Опять-таки, из чего следует? Семантика volatile как раз установлена стандартом, и выражается в сохранении последовательности чтения/записи таких данных. То есть — везде, где конструкцией языка подразумевается использование значения — оно читается, где подразумевается изменение — оно записывается. А уж каким конкретно образом сие будет реализовано — это, как и все остальное, implementation-defined.

ME>Никакой стандарт не гарантирует, что volatile вставит load инструкцию


Это уже дело компилятора — вставлять ли инструкцию, и какую именно. Стандарт предписывает сохранить "порядок чтения/записи".

К слову, не следует с таким пиететом относиться к стандарту. Это не настолько самодостаточный документ, чтобы объяснять все возможные нюансы. Например, он использует понятие "sequence of reads and writes to volatile data", но нигде не объясняет, где и отчего возникают эти "reads" и "writes", оперируя в дальнейшем высокоуровневыми понятиями.

ME>Во-первых, load инструкция, в-общем, не гарантирует загрузку актуального значения из памяти без использование барьеров памяти.


Опять двадцать пять. Ты снова начинаешь доказывать, что одного volatile недостаточно, хотя ни один из участников треда в этом с тобой не спорил. С тобой спорят только в части утверждения "volatile бесполезен и даже вреден".

ME>Есть тип, который гарантирует атомарность load и store на конкретной платформы для переменной этого типа — это sig_atomic_t. Только, почему-то, нет типа thread_atomic_t.


Может быть, потому, что в стандарте нет понятия "thread"?

ME>И сейчас утверждаю, что volatile бесполезен и вреден для multithreading.

ME>Одно из применений multithreading — получить максимальное быстродействие, задействовав все процессоры системы.

Только одно из. Изначально многопоточность возникла исключительно из стремления реализовать асинхронные по своей сути процессы в естественном виде, и лишь потом она удобно легла на многопроцессорную архитектуру.

ME> С другой стороны, volatile variables связывают руки оптимизатору. Звучит глупо: хочешь добиться максимального быстродействия, но запрещаешь оптимизацию.


Если бы ты изначально сформулировал свою мысль, как "volatile вреден для эффективного multithreading" — с тобой опять-таки никто не спорил бы. Я уже говорил о систематическом и необоснованном расширении тобой частных утверждений. Может, тебе стоит обращать больше внимания на соответствие того, что ты пишешь, тому, что при этом подразумеваешь? Телепаты, однако, в отпуску.

ME>Компилятор, который бы требовал применение volatile к thread shared variables для конкретной платформы по этой причине попросту бы там не продавался.


Да потому, что на данном этапе проще не упираться в столь тонкую оптимизацию в стандартных ее режимах, вот и все.

Для максимального быстродействия многопоточки volatile действительно вреден. А вот для максимальной надежности ее же он может быть исключительно полезен, ибо позволяет привязывать расстановку барьеров не к коду, а к данным. Если в многопоточном процессе типа "писатель-читатели" модификация объекта происходит редко, а использование — часто, то достаточно тяжело следить за расстановкой отдельных барьеров при каждом использовании. А volatile позволяет компилятору, которые знает про свою платформу и про барьеры, это дело соответствующим образом обеспечить.

ME>Приведи пункт стандарта или соответсвующий текст из reference manual к какой либо threading model


В другом ответе я привел цитату из MSDN (статья 120926). Но тебе она, конечно же, покажется неубедительной.

ME>Эта оговорка, а лучше сказать ошибка, сидит в секции C/C++ Language Reference с незапамятных времен. Как умеют люди из mictrosoft трактовать C++ стандарт и писать код на C++ мы все тут знаем.


Насчет того, что не стоит превозносить C++ Standard, я уже писал. Это тоже отнюдь не тот документ, на который нужно равняться в отношении ясности, прозрачности и непротиворечивости. MSDN выгребает хотя бы за счет объема и количества — порывшись в ней как следует, почти всегда можно найти правильный ответ (или, хотя бы, направление дальнейшего поиска). Где предлагаешь копаться, чтобы найти ответы на вопросы, не освещенные в стандарте C++?

А про "трактовку стандарта людьми из microsoft" — она в основном базируется на ламерских наездах на реализацию for и подобных конструкций в компиляторах до 7.0. Почитал человек стандарт 98 года, поставил себе VC++ 5.0 или 6.0, обнаружил там несоответствия — и давай привычно поливать MS А сообразить, что все эти компиляторы выпущены до принятия стандарта, ума не хватает. Много ли претензий по несовместимости со стандартом к компиляторам седьмой версии?

ME>Скачай Platform SDK, и найди в его документации упоминание о том, что thread shared variables должны быть volatile.


А где ты в этой документации нашел упоминания о том, что любые обращения к разделяемым данным должны быть защищены определенными примитивами синхронизации? Таких утверждений там тоже нет, говорится лишь, что доступ "must be synchronized". А как его синхронизировать — дело программиста. В частности, описаны варианты исключительно с volatile и без единого примитива ОС.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[14]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 19.01.05 12:41
Оценка:
emusic wrote:

> Здравствуйте, MaximE, Вы писали:

>
> ME>Это единственное упоминание volatile и multithreading в MSDN.
>
> Нет, это единственное упоминание, найденное тобой Ибо авторы MSDN не предполагали, что ты станешь искать непременно по слову multithreading. Поищи по thread или concurrent.

Я искал — безрезультатно.

> Еще про volatile есть статейка 324866 (a variable in the kernel that is used to manage the list of pending-event notifications was not declared as volatile).


Правильная статейка. volatile для этого и предназначен — для переменных изменяемых обработчиками сигналов и прерываний.

Хотя статья не имеет никакого отношения к multithreading.

> Кстати, в VC++ 7 появилась intrinsic-функция _ReadWriteBarrier. Это как раз случай барьера на уровне компилятора — в отличие от барьера на уровне аппаратуры.


Что это подтверждает или опровергает в контексте данной ветки?

> ME>Второе, нигде в секции MSDN DLLs, Processes and Threads не упоминается о том, что shared variables должны быть volatile.

>
> Опять-таки — с чего ты взял, что об этом должно упоминаться непременно в указанной секции? Если тебе удобно там это искать — MSDN-то при чем? А о том, что volatile может потребоваться для разделяемых данных, раз десять упомянуто в секциях описания языка, где идет речь об определениях переменных, квалификаторах, указателях и т.п.

Только в C/C++ Language Reference, C/C++ Language and C++ Libraries, Visual C++ Programmer's Guide — copy'n'paste. Все.

> По-моему, вполне резонно предполагать, что перед изучением Win API программист хотя бы в общих чертах ознакомится с языком вообще.


... Ознакомится и удивится, почему они приплели туда multithreading.

> Еще к VC++ 2.0 была статейка 120926:

> If the value of a variable can be modified by another thread or by the operating system and your program depends on this behavior, you should declare the variable as volatile. Without the volatile keyword, the optimizing compiler may enregister a copy of this variable, leading to unexpected behavior.

Они забыли дописать "or use syncronization functions".

> ME> Из этого следует, что это не является необходимым для win32 threading model.

>
> Если бы секция "DLLs, processes and threads" являлась исчерпывающей документацией по программированию многопоточных приложений на C/C++ под Win32 — тогда следовало бы.

Логично предположить, что вся необходимая документация к API содержится в его reference. В Process and Thread Reference нет ни требований, ни рекоммендаций делать переменные volatile.

> Оно явно и написано. Во многих местах, на разные лады. Если кому-то угодно читать лишь выборочно — это его личные трудности


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

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re: ужас
От: Seriously Serious  
Дата: 19.01.05 20:09
Оценка:
От этого всего у меня вопросы:
1) Гарантируется ли что-нибудь относительно порядка вызова функций синхронизации? или компилятор тут тоже может оптимизировать как захочет?
2) Имеет ли право компилятор все переменные держать в регистрах? (где об этом в стандарте сказано?)
Re[2]: ужас
От: MaximE Великобритания  
Дата: 19.01.05 22:55
Оценка:
Здравствуйте, Seriously Serious, Вы писали:

SS>От этого всего у меня вопросы:

SS>1) Гарантируется ли что-нибудь относительно порядка вызова функций синхронизации? или компилятор тут тоже может оптимизировать как захочет?

Гарантируется. После вызова "непрозрачной" ф-ции компилятор будет перечитывать значения всех переменных из памяти. В противном случае даже single threaded код работать не будет.

У компилятора просто нет никакой возможности установить, что изменяет "непрозрачная" ф-ция. К примеру, C++ runtime может сохранить адреса всех глобальных переменных и любая "непрозрачная" ф-ция может изменить значение какой либо глобальной переменной не принимая ее адреса явно в качестве параметра вызова. Компилятору знание об эффектах "непрозрачных функций" недоступно, поэтому ему придется перечитывать все переменные из памяти.

Ok, компилятору, обычно, известны эффекты всех ф-ций, которые выполняет его же C++ runtime, но это был лишь пример, и вместо C++ runtime может выступать любой C/C++ API, к исходникам которого у компилятора нет доступа.

SS>2) Имеет ли право компилятор все переменные держать в регистрах? (где об этом в стандарте сказано?)


Имеет, но см. п.1.
Re[19]: volatile у переменной класса
От: c-smile Канада http://terrainformatica.com
Дата: 20.01.05 00:45
Оценка:
Здравствуйте, achp, Вы писали:

A>Прохождение барьера всегда связано с вызовом внешней функции. Объект, к которому возможно обращение из нескольких потоков — либо глобальный, либо к нему ранее были созданы пути доступа, которые компилятор отследить не в силах. Следовательно, компилятор обязан предполагать возможность изменения данных объектов.


Как выглядит "барьер" в стандарте C++?
Re[19]: volatile у переменной класса
От: c-smile Канада http://terrainformatica.com
Дата: 20.01.05 00:51
Оценка:
Здравствуйте, achp, Вы писали:

A>Причем здесь это? Прохождение барьера всегда связано с вызовом внешней функции. Объект, к которому возможно обращение из нескольких потоков — либо глобальный, либо к нему ранее были созданы пути доступа, которые компилятор отследить не в силах. Следовательно, компилятор обязан предполагать возможность изменения данных объектов.


Что такое "внешняя" функция?
Для компилятора и линкера все функции "внутренние" так как сидят в соотв. lib файлах.
Re[3]: ужас
От: Шахтер Интернет  
Дата: 20.01.05 01:49
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Seriously Serious, Вы писали:


SS>>От этого всего у меня вопросы:

SS>>1) Гарантируется ли что-нибудь относительно порядка вызова функций синхронизации? или компилятор тут тоже может оптимизировать как захочет?

ME>Гарантируется. После вызова "непрозрачной" ф-ции компилятор будет перечитывать значения всех переменных из памяти. В противном случае даже single threaded код работать не будет.


ME>У компилятора просто нет никакой возможности установить, что изменяет "непрозрачная" ф-ция. К примеру, C++ runtime может сохранить адреса всех глобальных переменных и любая "непрозрачная" ф-ция может изменить значение какой либо глобальной переменной не принимая ее адреса явно в качестве параметра вызова. Компилятору знание об эффектах "непрозрачных функций" недоступно, поэтому ему придется перечитывать все переменные из памяти.


ME>Ok, компилятору, обычно, известны эффекты всех ф-ций, которые выполняет его же C++ runtime, но это был лишь пример, и вместо C++ runtime может выступать любой C/C++ API, к исходникам которого у компилятора нет доступа.


Ты забываешь про глобальную оптимизацию. В общем случае, гадать, что компилятор может соптимизировать, а что нет -- бесполезное занятие. Все такие догадки релевантны только применительно к конкретной платформе.

SS>>2) Имеет ли право компилятор все переменные держать в регистрах? (где об этом в стандарте сказано?)


ME>Имеет, но см. п.1.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[11]: volatile у переменной класса
От: Шахтер Интернет  
Дата: 20.01.05 01:49
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, emusic, Вы писали:


E>>Здравствуйте, MaximE, Вы писали:


ME>>>POSIX не требует volatile.


E>>Это личные предпочтения POSIX. Не более того. POSIX — замкнутая система, спецификация которой охватывает и аппаратную часть, и саму программу, и окружение программы. Это позволяет ей налагать дополнительные ограничения на поведение компилятора — в частности, на оптимизацию.


ME>Правилнее было бы сказать, что win32 — это закрытая система. POSIX — открытая, можешь разработать и внести свои предложения на рассмотрение. (например потребовать, чтоб volatile был нужен )


E>>Однако даже POSIX-совместимый компилятор совершенно не обязан предполагать, что значение любой переменной может измениться после вызова любой внешней функции


ME>Это так.


E>> — к этому его обязывают лишь вызовы известных системных функций.


ME>POSIX явно специфицирует какие функции являются барьерами.


ME>>>Осталось разобраться для win32.


E>>Кроме POSIX и Win32, в мире не существует больше платформ?


ME>Я говорю про то, что я знаю. На мой взгляд, POSIX и win32 — самые распространенные. Если ты специалист в mac, dec или еще каких threads, можешь просветить.


E>>В этом твоя главная ошибка — ты высказываешь общие утверждения, опираясь лишь на частные случаи. О том, что в POSIX достаточно барьеров, с тобой никто не спорил — это установлено спецификацией POSIX.


ME>Для меня POSIX и win32 — это 100% случаев.


А для меня -- нет. Есть ещё vxWorks, например.

ME>Хочешь обсудить другие платформы — тебе никто не запрещает.


E>>Однако нет всеобщей спецификации, которая гарантировала бы достаточность разного рода средств синхронизации в отсутствие volatile.


ME>Еще раз: POSIX volatile не нужен. В MSDN я также не нашел упоминания, что им нужен volatile. Делаю вывод, что для win32 он также не нужен.


Странный вывод. Win32 не налагает ограничений на компилятор, так что гарантий, что какой-нибудь gcc не захочет слишком хорошо соптимизировать нет никаких. Более того, даже родной Майкрософтовский VC++ может выдать гадость, поскольку Майкрософт компания большая, а в таких компаниях левая рука часто не знает, что делает правая.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Поведение C++ runtime
От: emusic Франция https://software.muzychenko.net/ru
Дата: 20.01.05 04:04
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>К примеру, C++ runtime может сохранить адреса всех глобальных переменных и любая "непрозрачная" ф-ция может изменить значение какой либо глобальной переменной не принимая ее адреса явно в качестве параметра вызова.


Охренеть. А что еще может сделать C++ runtime столь же неявно? Из того, что в описаниях библиотечных функций не оговорено, что эти функции не изменяют значений "левых" переменных, делаем вывод, что перед вызовом каждой функции нам нужно сохранять в файле значения всех глобальных переменных, а после возврата — восстанавливать? Стековый кадр, надеюсь, C++ runtime без спроса корежить не станет?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[8]: [2]: : volatile: а можно примеры?
От: c-smile Канада http://terrainformatica.com
Дата: 20.01.05 06:05
Оценка:
Здравствуйте, eao197, Вы писали:

E>Ничего личного, Шахтер, но я более склонен согласиться с Мейерсом, чем с вами


Советую внимательно глянуть на код с volatile.
Там продемонстрировано то что volatile не решает отдельную конкретную и нетривиальну проблему.

Но нигде Майерс не говорит о том что volatile не решает базовую проблему "указание компилятору на то что данная переменная можеть изменить значение вне normal flow программы".
Re[2]: volatile у переменной класса
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 20.01.05 06:27
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Vet wrote:


ME>volatile не имеет никакого отношения к multithreading, поэтому его применение в этой ситуации не только бесполезно, но может быть и вредно, так как с volatile компилятор не сможет соптимизировтать доступ к этой переменной. Но если один из потоков изменяет переменную, синхронизация при помощи мютексов обязательна.


Так надоело по крупицам вылавливать информацию о volatile и multithreading`ге и некоторых других особенностях плюсов, связанных с этим... Максим, если у вас богатый опыт в этом вопросе, может наконец-то статью напишете, где изложите все свои знания насчёт этих вопросов? Интересно было бы почитать...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re: Поведение C++ runtime
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.01.05 07:41
Оценка:
Здравствуйте, emusic, Вы писали:

E>Охренеть. А что еще может сделать C++ runtime столь же неявно? Из того, что в описаниях библиотечных функций не оговорено, что эти функции не изменяют значений "левых" переменных, делаем вывод, что перед вызовом каждой функции нам нужно сохранять в файле значения всех глобальных переменных, а после возврата — восстанавливать? Стековый кадр, надеюсь, C++ runtime без спроса корежить не станет?


Шутки-шутками, но допустим, я захотел, чтобы моя программа использовала мою функцию strlen. Я не описываю ее прототипа, т.к. он определен в <cstring>, просто прилинковываю к программе еще один obj или lib. Но задачей моей strlen, кроме основной работы, может быть, скажем сбор статистики. Или strlen помещает последнюю вычесленную длину в глобальную переменную, чтобы она была доступна без повторного обращения к strlen. Или кэширует адреса строк и их длины для того, чтобы повторно не вычислять длину той же самой строки. Для этого моя strlen модифицирует какие-либо глобальные данные. Которые могут быть определены даже в другой lib-е. Так вот мне интересно, имеет ли право компилятор, встретив где-то в коде strlen посчитать, что он все знает про эту функцию (она же из стандартной библиотеки) и оптимизировать все, что находится вокруг нее? Причем меня волнует компилятор, который, пока, делает основную оптимизацию, а не линкер, который-то явно будет знать, что strlen не стандартная.

Пример с strlen может быть и притянут с потолка. Но почему такого не может быть с malloc/free/realloc? Ведь предоставление своих версий глобальных new и delete является распространенной практикой.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: [2]: : volatile: а можно примеры?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 20.01.05 07:55
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Советую внимательно глянуть на код с volatile.

CS>Там продемонстрировано то что volatile не решает отдельную конкретную и нетривиальну проблему.

Там показано, что в многопоточной программе, даже с использованием примитивов синхронизации, volatile не дает ожидаемого от него эффекта. И если один раз volatile не срабатывает, то почему следует ожидать, что он сработает в остальных случаях?

CS>Но нигде Майерс не говорит о том что volatile не решает базовую проблему "указание компилятору на то что данная переменная можеть изменить значение вне normal flow программы".


А с этим я никогда и не спорил. Поэтому еще раз проясню свою позицию: я хочу увидеть реальные примеры (из реальных, а не тестовых примеров), когда использовались примитивы синхронизации, но приложение все равно работало не правильно до тех пор, пока не было использовано volatile. При этом меня не интересуют ни обработчики аппаратных прерываний, ни работа с железом через отображаемые в память порты ввода/вывода.

Прошу не приводить примеров, когда компилятору специальными ключами явно указывали, что ни одна функция не имеет побочных эффектов. Применение такого ключа в многопоточной программе, ИМХО, является проявлением излишнего оптимизма программиста. Кроме того, такой пример я уже видел. Может есть что-то еще?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 20.01.05 08:56
Оценка:
Здравствуйте, emusic, Вы писали:

E>Здравствуйте, c-smile, Вы писали:


CS>>EnterCriticalSection/LeaveCriticalSection это два раза полновесный вызов Scheduler что не способствует быстродействию никак.


E>Надо отдать должное реализации этих функций: если секция не захвачена другим потоком — объекты синхронизации не задействуются, все выливается только в вызовы InterlockedXXX.


И можно также взглянуть на эту структуру:
// winnt.h

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;

    //
    //  The following three fields control entering and exiting the critical
    //  section for the resource
    //

    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;


Каунтеры не объявлены как volatile.

Конечно, защитников volatile это не убедит, т.к. они скажут, что в ms знали особенности компилятора и нужные ключи компиляции, когда они компилировали ф-ции EnterCriticalSection et al.
Re[3]: ужас
От: Tom Россия http://www.RSDN.ru
Дата: 20.01.05 09:19
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Seriously Serious, Вы писали:


SS>>От этого всего у меня вопросы:

SS>>1) Гарантируется ли что-нибудь относительно порядка вызова функций синхронизации? или компилятор тут тоже может оптимизировать как захочет?

ME>Гарантируется. После вызова "непрозрачной" ф-ции компилятор будет перечитывать значения всех переменных из памяти. В противном случае даже single threaded код работать не будет.


Что такое "непрозрачные" функции, где о них упоминание в стандарте и кем карантируется то, что ты сказал?
Народная мудрось
всем все никому ничего(с).
Re[5]: volatile у переменной класса
От: Andrew S Россия http://alchemy-lab.com
Дата: 20.01.05 09:58
Оценка:
E>>Надо отдать должное реализации этих функций: если секция не захвачена другим потоком — объекты синхронизации не задействуются, все выливается только в вызовы InterlockedXXX.

ME>И можно также взглянуть на эту структуру:


ME>Каунтеры не объявлены как volatile.


ME>Конечно, защитников volatile это не убедит, т.к. они скажут, что в ms знали особенности компилятора и нужные ключи компиляции, когда они компилировали ф-ции EnterCriticalSection et al.


А что на нее глядеть? Она пользуется извне только для отладочных целей (соотв, когда никакой оптимизации и нет). Или вы думаете, что при компиляции kernel32.dll они пользуются winnt.dll из своего PSDK?
PS Вообще, знание структуры CS совсем не обязательно для ее нормального использования, точнее, оно вообще не нужно.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: ужас
От: Seriously Serious  
Дата: 20.01.05 10:06
Оценка:
А если ВСЕ функции станут прозрачными и компилятор будет ВСЁ держать в регистрах?
Re[20]: volatile у переменной класса
От: achp  
Дата: 20.01.05 10:15
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Как выглядит "барьер" в стандарте C++?


Барьер в стандарте Си/Си++ отсутствует. Отсюда следует, что единственный способ, которым он может быть выражен — вызов некоторой функции.
Я кончил, джентльмены, мне остается только поблагодарить вас за внимание.
Re[20]: volatile у переменной класса
От: achp  
Дата: 20.01.05 10:15
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, achp, Вы писали:


A>>Причем здесь это? Прохождение барьера всегда связано с вызовом внешней функции. Объект, к которому возможно обращение из нескольких потоков — либо глобальный, либо к нему ранее были созданы пути доступа, которые компилятор отследить не в силах. Следовательно, компилятор обязан предполагать возможность изменения данных объектов.


CS>Что такое "внешняя" функция?

CS>Для компилятора и линкера все функции "внутренние" так как сидят в соотв. lib файлах.

Внешняя в данном контексте значит "внешняя по отношению к данной единице комипляции" или иначе "определённая где-то за пределами данной единицы компиляции".

Кстати, конкретный вопрос. Назовите тот библиотечный файл, в котором "сидит" тело функции WaitForSingleObject.
Я кончил, джентльмены, мне остается только поблагодарить вас за внимание.
Re[11]: [2]: : volatile: а можно примеры?
От: achp  
Дата: 20.01.05 10:34
Оценка: +1
Здравствуйте, Andrew S, Вы писали:

AS>V2. Переменная объявлена не как volatile. Соотв, параметры InterlockedXxx без volatile (например, как это было в PSDK 2-х летней давности. Теперь это не так и вынуждает программистов использовать volatile для этих функций.


С какой радости? Преобразования указателей от менее cv-квалифицированных к более cv-квалифицированным происходят неявно.
Я кончил, джентльмены, мне остается только поблагодарить вас за внимание.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.