POD предоставляется специальная обработка при инициализации по умолчанию (c ++ 14)? - PullRequest
0 голосов
/ 07 мая 2018

Почему следующий код выдает 0 в качестве вывода? В моем понимании это инициализация по умолчанию (не инициализация значения), поэтому значение должно быть случайным.

#include <stdio.h>
#include<iostream>
#include<memory>

using namespace std;

struct A 
{

    int i;
    int j;
};


int main()
{
    A a;

    cout << " i is " << a.i << endl;

    return 0;
}

из cppreference:

Эффекты инициализации по умолчанию:

если T является типом класса не POD (до C ++ 11), конструкторы рассматриваются и подвергаются разрешению перегрузки для пустого списка аргументов. Выбранный конструктор (который является одним из конструкторов по умолчанию) вызывается для предоставления начального значения для нового объекта;

если T является типом массива, каждый элемент массива инициализируется по умолчанию;

в противном случае ничего не делается: объекты с автоматической продолжительностью хранения (и их подобъекты) инициализируются неопределенными значениями.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

То, что вы получаете за a.i, не определено, вы должны ожидать получить любое значение.

Зависит от системы, используемой библиотеки std, компилятора, флагов компилятора, ... некоторые части памяти (например, стек) могут быть инициализированы с 0, но это не гарантируется.

Это также верно для gcc, в вашем простом примере вы всегда можете получить 0, но если вы отключите оптимизацию -O0 и скомпилируете следующий код:

#include <iostream>

struct A 
{
  int i;
  int j;
};


int foo() {
  A a;
  const int b = a.i;
  a.i = 123;
  return b;
}

int main() {
  const int n1 = foo();
  const int n2 = foo();
  std::cout << n1 << " " << n2 << std::endl;
  return 0;
}

Тогда (в зависимости от библиотеки os, std, cpu ...) вы получите следующий вывод:

0 123

В обоих случаях a.i неинициализирован, для первого вызова a.i содержит некоторое «случайное» число, для второго вызова a может быть создано в том же месте, и на данный момент эта часть памяти может все еще содержать 123. Причина этого заключается в том, что A создается в стеке, и последующие вызовы off foo, скорее всего, приведут к тому, что a будет находиться по тому же адресу памяти в стеке.

0 голосов
/ 07 мая 2018

Основано на обсуждении, эксперимент. Это неопределенное поведение. POD не имеет специальной обработки при инициализации по умолчанию.

clang, MSVC всегда давал случайное значение, но gcc всегда давал 0. В конце концов, undefined не определен.

...