Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/21: Рейтинг темы: голосов - 21, средняя оценка - 4.62
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700

Использование неинициализированных переменных

18.08.2017, 12:52. Показов 4477. Ответов 41
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть простой код
C++
1
2
3
4
5
6
7
8
9
//g++  5.4.0
 
#include <iostream>
 
int main()
{
    int n;
    std::cout << n;
}
В общем то он работает, http://rextester.com/YOGFL91563

Но на stackoverflow разные мнения по поводу корректности использования не инициализированных переменных.
Вот мне интересно следующее:
1. Какие могут быть проблемы? Ведь int по умолчанию имеет значение 0, и если не ошибаюсь это требование стандарта.
2. Почему компиляторы выдают warning при использовании неинициализированных переменных? Просто что бы напомнить об этом если вдруг мы случайно забудем инициализировать переменную перед тем как используем её?
3. 2017 студия вообще отказывается компилировать код в котором используются не инициализированные переменные. Это фича такая и как то отключается? Типа "не компилить если есть хотя бы 1 warning"?

Прошу разъяснить тех кто знает

Добавлено через 1 минуту
Особенно интересует ответ на вопрос #1
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.08.2017, 12:52
Ответы с готовыми решениями:

Предупреждения компилятора об использовании неинициализированных переменных
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;time.h&gt; #include &lt;stdlib.h&gt; #define n 5 #define m 5 #define p 5 #define q 5 ...

Хранение неинициализированных объектов шаблонного класса
Допустим, есть шаблонный класс template &lt;typename T&gt; class SomeValue; который хранит в себе какое-то значение. И есть нешаблонный...

использование переменных
Программа использует много включаемых файлов, в которых достаточное количество циклов.. Как лучше объявлять переменную i ?? Отдельно в...

41
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.08.2017, 13:07
Цитата Сообщение от Undisputed Посмотреть сообщение
Какие могут быть проблемы?
не предсказуемое поведение
во многих кейсах.

Цитата Сообщение от Undisputed Посмотреть сообщение
Ведь int по умолчанию имеет значение 0, и если не ошибаюсь это требование стандарта.
вы ошибаетесь.

Цитата Сообщение от Undisputed Посмотреть сообщение
Просто что бы напомнить об этом если вдруг мы случайно забудем инициализировать переменную перед тем как используем её?
они переживают за программистов.
и обращают их внимание на потенциальную лажу.

Цитата Сообщение от Undisputed Посмотреть сообщение
Это фича такая и как то отключается?
это такая фича, которая отключается.

моральные люди ставят уровень предупреждений на максимум.
в режиме: "все предупреждения приравнивать к ошибкам".

аморальные - отключают фичу "предупреждать об опасности",
специально, что бы можно было писать дурно пахнущий код.
который, впрочем, работает так же, как выглядит.
1
1617 / 1182 / 553
Регистрация: 08.01.2012
Сообщений: 4,561
18.08.2017, 13:10
Цитата Сообщение от Undisputed Посмотреть сообщение
по умолчанию имеет значение 0
не уверен, но вроде только для глобальных
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
18.08.2017, 13:18  [ТС]
hoggy,
А что там может быть непредсказуемого? Есть переменная, начальное значение которой равно нулю
Можно плз пример? А то многие говорят что это плохо но почему именно не объясняется )

А что стандарт говорит по этому поводу? еще не помню где, но читал что такая запись int n{} гарантирует то что переменная будет иметь значение 0, даже если явно не прописать. И warning-ов при такой записи не бывает. Если значения по умолчанию у int-a нет, то откуда берётся этот ноль?
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
18.08.2017, 13:24
Лучший ответ Сообщение было отмечено Undisputed как решение

Решение

Цитата Сообщение от Undisputed Посмотреть сообщение
Есть переменная, начальное значение которой равно нулю
С чего вдруг оно будет равно нулю?
Цитата Сообщение от Undisputed Посмотреть сообщение
А то многие говорят что это плохо но почему именно не объясняется
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <cstring>
 
void init(bool &x)//эмуляция рандомного значения в памяти
{
    memset(&x, 10, sizeof(bool));
}
 
 
 
int main()
{
    bool x;
    init(x);
    if (x == true) {
        std::cout << "is true" << std::endl;
    }
    if (x == false) {
        std::cout << "is false" << std::endl;
    }
}
http://rextester.com/RRJX62576
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
int main()
{
    bool x;
    std::cout << "start" << std::endl;
    if (x == true) {
        std::cout << "x is true";
    }
    if (x == false) {
        std::cout << "x is false";
    }    
}
http://rextester.com/WJVD11894

Добавлено через 26 секунд
Цитата Сообщение от Undisputed Посмотреть сообщение
int n{}
Это уже будет инициализированная переменная.
3
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
18.08.2017, 13:25
Цитата Сообщение от Undisputed Посмотреть сообщение
А что там может быть непредсказуемого?
Ну выведется в консоль неизвестно что. То есть например 20 раз выдало 0, потом на 21 выдало 17893, на 22 выдало -2343444.
Если бы у тебя в коде было написано
C++
1
std::cin >> n;
то никаких вопросов такой код не вызвал - если переменная будет присвоена/получена откуда-то, а до этого ей никто не будет пользоваться - неопределённого поведения не будет.
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
18.08.2017, 13:26
Лучший ответ Сообщение было отмечено gru74ik как решение

Решение

Цитата Сообщение от Undisputed Посмотреть сообщение
А что стандарт говорит по этому поводу?
Для фундаментальных типов значение неинициализированных переменных не определено.
C++
1
int x;//<--здесь мусор, если данные не статические и не потоковые
2
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
18.08.2017, 13:33
Цитата Сообщение от Undisputed Посмотреть сообщение
Ведь int по умолчанию имеет значение 0
Нет такого требования в стандарте. Сделано специально, чтоб не тратить такты процессора на заполнение памяти/регистров нулями в том случае, если их нужно будет сразу после этого заполнять чем-то другим.
2
18 / 17 / 16
Регистрация: 04.07.2017
Сообщений: 36
18.08.2017, 13:35
Цитата Сообщение от Undisputed Посмотреть сообщение
и если не ошибаюсь это требование стандарта
извольте тогда приложить выпись из стандарта

имеют значение по умолчанию
Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5)
before any other initialization takes place.
не имеют
When storage for an object
with automatic or dynamic storage duration is obtained, the object has an indeterminate value
Думаю, остальные вопросы опускаются. Т.е. если у тебя объявлен, напр., глобальный int, то все ОК, никаких проблем.
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
18.08.2017, 13:36
Цитата Сообщение от Undisputed Посмотреть сообщение
Если значения по умолчанию у int-a нет, то откуда берётся этот ноль?
Такие правила инициализации.
Возьмите стандарт и почитайте о видах и правилах инициализации.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
18.08.2017, 13:41  [ТС]
Croessmah,
Спасибо что объяснили!
Подскажите ещё плиз по следующим вопросам:
1. Выходит на значение по умолчанию можно расчитывать только если мы используем пользовательский тип (экземпляр класса с явно определенным конструктором по умолчанию?)
2. Если мы не определим конструктор по умолчанию и у класса есть поля например int, float тогда там тоже будет мусор независимо от того объект был создан в стеке или куче?
3. Какие значения принимают базовые типы при использовании фигурных скобок? Если долго перечислять то можно плз ссылку где можно об этом прочитать?
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
18.08.2017, 13:42
Цитата Сообщение от Undisputed Посмотреть сообщение
Выходит на значение по умолчанию можно расчитывать только если мы используем пользовательский тип
Нет.
Цитата Сообщение от Undisputed Посмотреть сообщение
Если мы не определим конструктор по умолчанию и у класса есть поля например int, float тогда там тоже будет мусор независимо от того объект был создан в стеке или куче?
Нет.
Цитата Сообщение от Undisputed Посмотреть сообщение
где можно об этом прочитать?
В стандарте.
Цитата Сообщение от Croessmah Посмотреть сообщение
Возьмите стандарт и почитайте о видах и правилах инициализации.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
18.08.2017, 13:56  [ТС]
Quaentor,
Глобальный int это так?

C++
1
2
3
4
5
6
7
8
9
10
//g++  5.4.0
 
#include <iostream>
 
int n;
 
int main()
{
    std::cout << n;
}
Плз скажите кто нибудь в какой именно части стандарта можно прочитать о значениях для типов в тех случаях когда нет явной инициализации но переменная либо глобальная как выше либо определилась при помощи фигурных скобок
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
18.08.2017, 14:01
Цитата Сообщение от Undisputed Посмотреть сообщение
в какой именно части стандарта можно прочитать о значениях для типов в тех случаях когда нет явной инициализации
Declarators -> Initializers
Неожиданно, да?
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
18.08.2017, 15:00  [ТС]
Croessmah,
Спасибо)

Но вот тут я ни разу не понял http://rextester.com/RRJX62576
Как оно тру и фолс одновременно
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
18.08.2017, 15:15
Цитата Сообщение от Undisputed Посмотреть сообщение
Как оно тру и фолс одновременно
То есть другой случай, в котором оно не true и не false понятен?
В этом случае тот же самый принцип.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
18.08.2017, 15:23
Undisputed, потому что true в С++ обычно компилируется как 1, а у тебя в байт переменной типа bool записывается 10 . 1 == 10 имеет значение false.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
18.08.2017, 15:47  [ТС]
Croessmah,
В том случае где не тру и не фолс понятно т.к там бывает мусор который как бы не тру и не фолс... Данных вообще нет. Даже нулей...
А здесь именно что есть данные, поэтому не понятно...

TRam_,
Сложно верится в такую интерпретацию, объясню почему:
Фолс насколько я понимаю бывает только в том случае когда все биты нулевые(то есть число 0), во всех остальных случаях должно быть true, или не так?
В данном случае мы записали в булеву переменную биты числа 10, а значит не все биты у нас нулевые. Поэтому не понятно почему сравнение с фолсом возвращает истину
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.08.2017, 16:16
Цитата Сообщение от Undisputed Посмотреть сообщение
Сложно верится в такую интерпретацию
господин TRam_ абсолютно прав.
true == 1
false == 0

это вполне четко определенные константы

в то время, как bool обычно занимает 1 байт.
в 1 байте обычно 8 бит.
это - 256 различных значений.

если загнать по адресу булевой переменной всякий мусор
(или просто оставить её не инициализированной)

то в этом байте получим все что угодно,
но скорее всего не 1 и не 0

Цитата Сообщение от Undisputed Посмотреть сообщение
Фолс насколько я понимаю бывает только в том случае когда все биты нулевые(то есть число 0), во всех остальных случаях должно быть true, или не так?
именно так.
true - все что не false.

если мы сделаем:

C++
1
bool b = 10; // stored true
то в переменную запишется 1, а не 10
0
Эксперт CЭксперт С++
 Аватар для liv
5120 / 4574 / 855
Регистрация: 07.10.2015
Сообщений: 9,462
18.08.2017, 16:17
Undisputed, Вы путаете два момента:
1) Когда само число интерпретируется, как логическое выражение.
Если написать if (10), то получим истину, т.к. 10 != 0, и if(0) даст ложь
2) Когда происходит сравнение числа с чем-то, тогда логическим выражением будет результат сравнения.
if (true == 10) даст ложь, т.к. 1 != 10. И if (false == 10) также даст ложь, ибо и 0 != 10

Ваша программка вообще-то не выведет ничего, т.к. оба условия ложны
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.08.2017, 16:17
Помогаю со студенческими работами здесь

Использование файловых переменных
помогите пожалуста с задачей. Только пожалуйста с кодом С.:( Дан файл f, содержащий свединья о книгах. Свединье о каждой книге - это...

Использование динамических переменных
Необходимо используя динамические переменные и функции написать следующее: Дан массив размера N и целые числа K и L (0 ≤ K ≤...

Использование динамических переменных
Объясните смысл использования динамических переменных. Я практиковался их создавать, использовать. Конкретно в чём плюс динамических...

Использование переменных main из класса
Создал класс, подключил так: #include &lt;stdio.h&gt; #include &lt;iostream&gt; #include &lt;fstream&gt; #include &quot;kartoteka.h&quot; #include...

Использование переменных из другой структуры
Добрый день, подскажите пожалуйста как реализовать такую вещь struct one{ void * a; int b; int c; }; struct two{ void *...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru