Инициализация: =, () и {}
Значение, которое переменная получает при объявлении, называют начальным, а сам этот шаг — инициализацией (initialization). Если значение не подходит к типу переменной, компилятор сам его преобразует, и часть значения может пропасть:
#include <iostream>
int main() {
double price = 2.9;
int whole = price;
std::cout << whole << '\n'; // 2
}int хранит только целые числа, поэтому дробная часть 0.9 отбрасывается — без округления. Компилятор не сообщает ни об ошибке, ни о предупреждении, и программа печатает 2.
Три формы записи
Начальное значение можно записать тремя способами:
int a = 5;
int b(5);
int c{5};
std::cout << a << ' ' << b << ' ' << c << '\n'; // 5 5 5Для int и 5 все три строки делают одно и то же. Различаются они тем, как обращаются с неподходящим значением: = и круглые скобки его преобразуют, как в примере выше.
Пустые фигурные скобки задают ноль: int total{}; значит то же, что int total{0};. Форма с = привычнее и встречается чаще всего, а чем лучше фигурные скобки, показывает следующий пример.
Скобки против сужения
Преобразование, при котором может пропасть часть значения, называют сужающим (narrowing). Так бывает, когда дробное число попадает в целый тип или число не помещается в новый тип. Важен не размер типа в байтах, а то, может ли пропасть часть значения. Фигурные скобки сужение запрещают:
int count{2.5}; // ✗error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]Это ошибка компиляции: программа не соберётся, пока значение не исправят. Константу, которая помещается в новый тип точно, скобки пропускают: double ratio{2}; компилируется. Сужением будет и int whole{price}; из первого примера: в price может оказаться дробное число. Поэтому фигурные скобки — самая строгая из трёх форм: ошибку с типом они находят сразу.
Частая ошибка
Переменную объявили без начального значения, а потом прочитали:
int total;
total = total + 5; // ✗warning: variable 'total' is uninitialized when used here [-Wuninitialized]У переменной, объявленной внутри функции без начального значения, значение не определено. Чтение такого значения — неопределённое поведение (undefined behavior): стандарт C++ не говорит, что сделает программа. Компилятор только предупреждает, поэтому задавайте значение сразу: int total{0}; или int total{};.