Мне интересно, если анализ псевдонимов проходит внутри clang или gcc, обрабатывают ли ссылочные переменные члена C ++ иначе, чем переменные-указатели. Если бы компилятор мог использовать некоторые из более строгих правил в отношении ссылок, это был бы аргумент, основанный на производительности, для предпочтения ссылок над указателями.
Одним из способов доказать это был бы битовый код, в котором изменение между ссылкой и указателем изменило сборку.
Вот пример кода, который может привести к разнице:
struct FooRef {
FooRef(int &i) : i_(i) {}
int &i_;
int add(int a, int *messWithAliasAnalysis) { *messWithAliasAnalysis= 0; return i_ + a; }
};
struct FooPtr {
FooPtr(int *i) : i_(i) {}
int *i_;
int add(int a, int *messWithAliasAnalysis) { *messWithAliasAnalysis= 0; return *i_ + a; }
};
// These functions are here to force the compiler to compile the add functions.
int foo(FooPtr &fooPtr, int *messWithAliasAnalysis) {
return fooPtr.add(5, messWithAliasAnalysis);
}
int foo(FooRef &fooRef, int *messWithAliasAnalysis) {
return fooRef.add(5, messWithAliasAnalysis);
}
Но с gcc 4.6 это не так. Одна и та же сборка генерируется для обеих функций foo.
Какие «ограничительные правила в отношении ссылок» вы имеете в виду? В вашем примере:
int x;
FooRef r(x);
foo(r, &x);
…создает случай, когда *messWithAliasAnalysis
а также i_
одно и то же целое число.
C ++ не имеет стандартной поддержки restrict, но многие компиляторы имеют эквиваленты, которые обычно работают как на C ++, так и на C, такие как коллекция компиляторов GNU ограничивать и Visual C ++ __restrict и __declspec (restrict).
http://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html
http://msdn.microsoft.com/en-us/library/5ft82fed.aspx
И gcc, и VC ++ поддерживают __restrict в C ++ для указателей, но только gcc поддерживает его для ссылок — поскольку ссылки не могут быть повторно установлены без неопределенного поведения, поэтому компилятор может статически определять псевдонимы.