Инициализация ссылочного члена сама по себе является законной?

Это была ошибка, которую я нашел в серверном приложении, используя Valgrind.

struct Foo
{
    Foo(const std::string& a)
        : a_(a_)
    {
    }
    const std::string& a_;
};

с gcc -Wall вы не получите предупреждение. Почему этот юридический код?

Ответ 1

Что вы нарушили 8.3.2/4 A ... reference shall be initialized to refer to a valid object or function. Так что это, безусловно, незаконно.

Обратите внимание, что не все ошибочные программы должны быть обнаружены компилятором, хотя я честно считал, что это один из них.

Для чего стоит g++ версия 4.4.1 с включенными предупреждениями о максимальном компиляторе, с радостью принимает эту программу без предупреждения:

int main(void)
{   
    int *p = 0;
    *p = 5;
}

Ответ 2

Самосознание разрешено в C/С++ (и я считаю это ошибкой на языке).

С точки зрения модели памяти Foo:: a_ - это просто место в памяти, а в списке инициализаторов ему присваивается значение другой ячейки памяти, которая в данном конкретном случае, к сожалению, является тем же самым местоположением.

В C есть аналогичный дефект, где вы можете сделать это:

  void foo() 
  {
    int i = i;
  }