Gcc: Как правильно использовать __attribute((__may_alias__)) чтобы избежать предупреждения «разыменование указателя, набC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Gcc: Как правильно использовать __attribute((__may_alias__)) чтобы избежать предупреждения «разыменование указателя, наб

Сообщение Anonymous »

У меня есть код, который использует каламбур, чтобы избежать необходимости вызывать конструктор и деструктор "объекта"-члена до тех пор, пока не возникнет необходимость использовать объект.
Это работает нормально, но в g++ 4.4.3 я получаю это ужасное предупреждение компилятора:
jaf@jeremy-desktop:~$ g++ -O3 -Wall puns.cpp
puns.cpp: In instantiation of ‘Lightweight’:
puns.cpp:68: instantiated from here
puns.cpp:12: warning: ignoring attributes applied to ‘Heavyweight’ after definition
puns.cpp: In destructor ‘Lightweight::~Lightweight() [with T = Heavyweight]’:
puns.cpp:68: instantiated from here
puns.cpp:20: warning: dereferencing type-punned pointer will break strict-aliasing rules
puns.cpp: In member function ‘void Lightweight::MethodThatGetsCalledRarely() [with T = Heavyweight]’:
puns.cpp:70: instantiated from here
puns.cpp:36: warning: dereferencing type-punned pointer will break strict-aliasing rules

Мой код пытается использовать __attribute((__may_alias__)) gcc, чтобы сообщить gcc о потенциальном псевдониме, но gcc, похоже, не понимает, что я пытаюсь ему сказать. Я делаю что-то не так, или у gcc 4.4.3 просто проблемы с атрибутом __may_alias__?
Игрушечный код для воспроизведения предупреждения компилятора приведен ниже:
#include
#include // for placement new
#include // for rand()

/** Templated class that I want to be quick to construct and destroy.
* In particular, I don't want to have T's constructor called unless
* I actually need it, and I also don't want to use dynamic allocation.
**/
template class Lightweight
{
private:
typedef T __attribute((__may_alias__)) T_may_alias;

public:
Lightweight() : _isObjectConstructed(false) {/* empty */}

~Lightweight()
{
// call object's destructor, only if we ever constructed it
if (_isObjectConstructed) (reinterpret_cast(_optionalObject._buf))->~T_may_alias();
}

void MethodThatGetsCalledOften()
{
// Imagine some useful code here
}

void MethodThatGetsCalledRarely()
{
if (_isObjectConstructed == false)
{
// demand-construct the heavy object, since we actually need to use it now
(void) new (reinterpret_cast(_optionalObject._buf)) T();
_isObjectConstructed = true;
}
(reinterpret_cast(_optionalObject._buf))->DoSomething();
}

private:
union {
char _buf[sizeof(T)];
unsigned long long _thisIsOnlyHereToForceEightByteAlignment;
} _optionalObject;

bool _isObjectConstructed;
};

static int _iterationCounter = 0;
static int _heavyCounter = 0;

/** Example of a class that takes (relatively) a lot of resources to construct or destroy. */
class Heavyweight
{
public:
Heavyweight()
{
printf("Heavyweight constructor, this is an expensive call!\n");
_heavyCounter++;
}

void DoSomething() {/* Imagine some useful code here*/}
};

static void SomeMethod()
{
_iterationCounter++;

Lightweight obj;
if ((rand()%1000) != 0) obj.MethodThatGetsCalledOften();
else obj.MethodThatGetsCalledRarely();
}

int main(int argc, char ** argv)
{
for (int i=0; i

Подробнее здесь: https://stackoverflow.com/questions/631 ... ncing-type
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»