Минимальный код воспроизведения на MSVC 2005 вот такой:
struct tagData{
int somemember;
};
volatile struct tagData dataArray[10];
int funnyError(volatile struct tagData data){
return data.somemember;
}
int main(int/* argc */, char** /* argv */){
dataArray[0].somemember = 1;
int x = funnyError(dataArray[0]);
return 0;
}
Получается классное сообщение об ошибке компиляции:
1>d:\programming\vcpp\research\funnyerr\funnyerr.cpp(13) : error C2664: 'funnyError' : cannot convert parameter 1 from 'volatile tagData' to 'volatile tagData'
1> Cannot copy construct struct 'tagData' due to ambiguous copy constructors or no available copy constructor
Вопрос к сообществу: что бы вы сделали, чтобы заставить это работать?
Моё решение -- передавать по указателю. То есть вот так:
struct tagData{
int somemember;
};
volatile struct tagData dataArray[10];
int funnyError(volatile struct tagData* data){
return data->somemember;
}
int main(int/* argc */, char** /* argv */){
dataArray[0].somemember = 1;
int x = funnyError(dataArray);
return 0;
}
Всё компилится и работает. Но мб есть иные методы?
Здравствуйте, Tilir, Вы писали:
T>Минимальный код воспроизведения на MSVC 2005 вот такой:
T>Получается классное сообщение об ошибке компиляции:
T>
1>>d:\programming\vcpp\research\funnyerr\funnyerr.cpp(13) : error C2664: 'funnyError' : cannot convert parameter 1 from 'volatile tagData' to 'volatile tagData'
1>> Cannot copy construct struct 'tagData' due to ambiguous copy constructors or no available copy constructor
T>Вопрос к сообществу: что бы вы сделали, чтобы заставить это работать?
Конструктор копирования, который генерируется по-умолчанию, имеет сигнатуру:
tagData& tagData::tagData(tagData const&);
Соотв. он не может принимать volatile объекты.
Тебе надо определить свой:
Но на этом сюрпризы не закончатся. operator = тоже не будет работать. При этом он не только не умеет принимать volatile объекты, но и не может вызываться для volatile объекта. Т.е. тебе надо будет определить свой:
Вообще я лично пришёл к выводу, что объявление объектов типа класс с квалификатором volatile, ни к чему хорошему не приводит, и лучше так вообще не делать — больше проблем. volatile лучше объявлять только объекты примитивных типов, для них всё работает интуитивно по-умолчанию. Т.е. в твоём случае вот так:
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Вообще, конечно, забавно, что играться с CV квалификаторами мемберов и явных параметров функций можно, на как быть с this
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>Вообще, конечно, забавно, что играться с CV квалификаторами мемберов и явных параметров функций можно, на как быть с this
Дык у меня как раз без копипаста порождалось семейство...
Тогда что-то вроде, но не так ужасно в использовании:
struct X
{
template<typename T> // упрощенно, на самом деле будет conditional<>::type, напримерstatic// ыыыыы :`(void f(T * This)
{
std::cout << typeid(This).name() << std::endl;
}
};
int main()
{
X x;
X::f(&x);
X::f(static_cast<X const*>(&x));
X::f(static_cast<X volatile*>(&x));
X::f(static_cast<X const volatile*>(&x));
}
Хотя интерес больше академический, скорее лучше имена разные давать:
// volatile инстанс по адресу 0x7ffe0014 даёт аналог NtQuerySystemTime без перехода в ядроstruct system_time
{
typedef int64_t type;
__forceinline type get() volatile const
{
uint32_t l; int32_t h;
if ( sizeof(std::uintptr_t) > sizeof(int32_t) )// don't like #ifdef _M_X64return *reinterpret_cast<int64_t volatile const*>(this);
do { cpu::pause(); l = low; h = high; }
while ( h != high2 );
return (type)h << 32 | l;
}
__forceinline operator type() const
{
return (type)high << 32 | low;
}
uint32_t low;
int32_t high, high2;
};
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth