Я ищу ответ на следующий вопрос: may_alias
подходит как атрибут для указателя на объект некоторого класса Foo
? Или он должен использоваться только на уровне класса?G ++: Может ли __attribute __ ((__ may_alias__)) использоваться для указателя на экземпляр класса, а не на определение класса?
Рассмотрим следующий код (он основан на реальном примере, который является более сложным):
#include <iostream>
using namespace std;
#define alias_hack __attribute__((__may_alias__))
template <typename T>
class Foo
{
private:
/*alias_hack*/ char Data[sizeof (T)];
public:
/*alias_hack*/ T& GetT()
{
return *((/*alias_hack*/ T*)Data);
}
};
struct Bar
{
int Baz;
Bar(int baz)
: Baz(baz)
{}
} /*alias_hack*/; // <- uncommeting this line apparently solves the problem, but does so on class-level(rather than pointer-level)
// uncommenting previous alias_hack's doesn't help
int main()
{
Foo<Bar> foo;
foo.GetT().Baz = 42;
cout << foo.GetT().Baz << endl;
}
Есть ли способ, чтобы сказать, что GCC одного указателя may_alias
какой-то другой?
Кстати, обратите внимание на то, что механизм обнаружения gcc такой проблемы несовершенен, поэтому очень просто просто предупредить об этом предупреждение, не решив проблему.
Рассмотрим следующий фрагмент кода:
#include <iostream>
using namespace std;
int main()
{
long i = 42;
long* iptr = &i;
//(*(short*)&i) = 3; // with warning
//(*(short*)iptr) = 3; // without warning
cout << i << endl;
}
Раскоментируйте один из линий, чтобы увидеть разницу в выходе компилятора.
Не понимаю. Я не знаю механизм управления gcc строгого псевдонима (и связанного с ним материала, как этот атрибут 'may_alias'), но я не вижу проблемы с отключением некоторой оптимизации для чтения/записи, которые используют один конкретный указатель. –
Или вы подразумеваете, что, например, для следующего фрагмента кода 'Foo foo; Foo alias_hack * fooPtr; 'запись с использованием fooPtr, а затем чтение с использованием foo напрямую может привести к неправильному значению из-за оптимизации? Но опять же, я не вижу проблем с этим, я не отмечал «foo» с необходимым атрибутом, но я сделал это для fooPtr. –
Может быть, я просто что-то пропустил –