#include <iostream>
volatile const char* p = "0";
int main() {
std::cout << p << std::endl;
return 0;
}
Для получение схожего эффекта в GCC надо заменить "0" на "false".
Blog about programming for beginners and beyond / Блог о программировании. Для начинающих и не только.
#include <iostream>
volatile const char* p = "0";
int main() {
std::cout << p << std::endl;
return 0;
}
Для получение схожего эффекта в GCC надо заменить "0" на "false".
В конце стоило все-таки объяснить, почему это работает именно так :)
ОтветитьУдалитьПотому что volatile const char* не приводится, согласно стандарту, к "просто" const char*, соответственно метод вывода в поток, определенный для "просто" const char* (прочитать строку по указателю) не применим. Ближайшее приведение, доступное компилятору - это приведение указателя к bool, что он и делает (и выводит значение true).
ОтветитьУдалитьНу вообще-то тема действительно старая. Встречался с ней когда изучал перегруженные операторы. В STL не все необходимые операторы перегружены, операторы с аргументами:
ОтветитьУдалитьchar*
const char*
volatile char*
volatile const char*
это все разные операторы и друг к другу они не приводятся просто так.
я бы сказал, что «волатильная константа» — это, скорее, дыра в стандарте, нет?
ОтветитьУдалитьНе уверен что это следует понимать как дыру. Скорее переменную "volatile const" следует понимать как read-only переменную, которая тем не менее может измениться (например, железом).
ОтветитьУдалитьсовершенно верно.
ОтветитьУдалитьно боюсь, если мы вынуждены догадываться, как следует понимать ту или иную конструкцию — это и есть лакуна в стандарте, увы.
Например у нас есть контроллер датчика температуры. Датчик записывает значение температуры в память по DMA. Переменную, которая будет отображать этот кусок памяти, однозначно надо делать const (ибо можно в коде ошибку сделать), но она должна зачитываться при каждом обращении. Вот вам совершенно логичный пример "volatile const" без всяких дыр
ОтветитьУдалитьАхтунг. При таком неявном преобразовании к bool хотелось бы видеть warning. В MSVC STL реализация оператора на консоль выводит 0 или 1. А в GCC - true или false. А вопрос и вправду каверзный ;)
ОтветитьУдалитьраз уж тут такие интересные вещи обсуждаются, объясните пожалуйста почему:
ОтветитьУдалить&(*(ptrObj->ptrObj2)) - создается unnamed pointer на новый объект, поразрядную копию Obj2.
а при:
&(*ptrObj) - это тот же ptrObj pointer на все тот же Obj?
Заранее благодарен за ответ.
@kostiantyn: а можно более развернутый пример?
ОтветитьУдалить@Александр: прошу прощения, сам себя перепутал и Вас попытался заодно с толку сбить. У меня в коде намного более сложный случай, объекты довольно таки комплексные. Вот я и не разобрался сразу. Только когда написал по Вашей просьбе более простой пример, аналог того, что у меня в коде происходит, он мне и показал, что операция &(*ptr) таки ничего не копирует в случае со сложными объектами. Будь то просто указатель или указатель внутри того, на что указывает указатель.
ОтветитьУдалить(В теории вроде осуществляется копирование простого объекта интегрального типа из хипа в стек при применении операции разименовывания, но это явно не мой случай.)
@kostiantyn: Факт. Всегда полезно попытаться объяснить проблему другому программисту, и часто в процессе объяснения наступает просветление для самого объясняющего, и проблема решается сама собой ;-). Удачи.
ОтветитьУдалитьНе обязательно даже "другому программисту". ;-) http://en.wikipedia.org/wiki/Rubber_duck_debugging
ОтветитьУдалить