Использована неинициализированная локальная переменная c как исправить

Error C4700: использована неинициализированная локальная переменная C++ Решение и ответ на вопрос 2177650

Ilya-Glushko

0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

1

21.01.2018, 15:11. Показов 19159. Ответов 19

Метки калькулятор систем счисления (Все метки)


При компиляции выдаёт вот такие ошибки:
error C4700: использована неинициализированная локальная переменная «y»
error C4700: использована неинициализированная локальная переменная «x»

P.S Пробовал переставлять объявления и менял их, не помогает.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <stdlib.h>
#include <iomanip>
using namespace std;
 
int main()
{
 
    setlocale(0, "");
    double num;
    cout << "Введите число 1 - умножение, 2 - деление. ";
    cin >> num;
    if (num = 1)
    {int a, b;
 
    cout << "Введите первое число: ";
    cin >> a;
    cout << "Введите второе число: ";
    cin >> b;
    int c = a * b;
    cout << "Результат = " << c << endl; 
    }
 
 
    else if (num = 2)
    setlocale(0, "");
    
    cout << "Введите число 2 - деление ";
    cin >> num;
    int x, y;
        int c = y / x;
    if (num = 2)
 
            
    cout << "Введите первое число: ";
    cin >> x;
    cout << "Введите второе число: ";
    cin >> y;
    cout << "Результат = " << c << endl;
    }

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



139 / 67 / 46

Регистрация: 15.10.2015

Сообщений: 308

21.01.2018, 15:21

2

Инициализируйте X и Y нулями.



0



3926 / 2844 / 660

Регистрация: 08.06.2007

Сообщений: 9,641

Записей в блоге: 4

21.01.2018, 15:23

3

Лучший ответ Сообщение было отмечено Ilya-Glushko как решение

Решение

Переставить строку 31 и поставить ее после 38-й.

Добавлено через 1 минуту

Цитата
Сообщение от Reavolt
Посмотреть сообщение

Инициализируйте X и Y нулями.

Это приведет к делению на нуль в строке 38.



1



139 / 67 / 46

Регистрация: 15.10.2015

Сообщений: 308

21.01.2018, 15:25

4

Цитата
Сообщение от palva
Посмотреть сообщение

Это приведет к делению на нуль в строке 38.

Ему не кто не запрещает инициализировать их 1. Я не читал код, так-как из самой ошибки понятно, в чем проблема.



1



pain1262

6 / 6 / 7

Регистрация: 24.09.2016

Сообщений: 63

21.01.2018, 15:35

5

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
void main()
{
    setlocale(LC_ALL, "RUS");
    int num = 0, a = 0, b = 0;
    double c = 0;
    cout << "Введите число 1 - умножение, 2 - деление. "; cin >> num;
    if (num == 1)
    {
        cout << "Введите первое число: "; cin >> a;
        cout << "Введите второе число: "; cin >> b;
        c = a * b;
        cout << "Результат = " << c << endl;
    }
    if (num == 2)
    {
        cout << "Введите первое число: "; cin >> a;
        cout << "Введите второе число: "; cin >> b;
        c = a / b;
        cout << "Результат = " << c << endl;
    }
}



0



0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 15:42

 [ТС]

6

Спасибо, помогло.

Добавлено через 3 минуты
С помощью этого не произойдет деление.



0



7423 / 5018 / 2890

Регистрация: 18.12.2017

Сообщений: 15,694

21.01.2018, 16:11

7

Ilya-Glushko, сбросьте условие задачи



0



0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 16:15

 [ТС]

8

Yetty, задачи поставленно небыло, я просто хотел сделать калькулятор с выбором умножения и деления, щас дорабатывать буду, кстати у меня ещё одна проблема…



0



7423 / 5018 / 2890

Регистрация: 18.12.2017

Сообщений: 15,694

21.01.2018, 16:20

9

Ilya-Glushko, дело не в инициализации (она вообще не нужна если не переназначать переменные), а в обработке возможной попытки деления на нуль.



0



0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 16:40

 [ТС]

10

Yetty, Что вы предлагаете? Можете конкретно показать? Сразу оговорюсь если я использую std::, не запускается, так что не делайте на это расчет.

З.Ы Visual Studio 2017

Добавлено через 36 секунд
palva, да, помогло…



0



Yetty

7423 / 5018 / 2890

Регистрация: 18.12.2017

Сообщений: 15,694

21.01.2018, 16:41

11

Цитата
Сообщение от Ilya-Glushko
Посмотреть сообщение

Yetty, Что вы предлагаете? Можете конкретно показать?

примерно так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;
 
int main()
{    
    int n=1, num;
    double a, b, eps=0.0000000001;
        while (n==1)
{
        cout << "a="; cin >> a;
        cout << "b="; cin >> b;
        do
    {  
        cout << "1x or 2: "; cin >> num;
        if (num!=1 && num!=2) cout <<"Enter error/Repeat please.";
    }
    while (num!=1 && num!=2);
    if (num == 1) cout <<"c="<<a * b;
    if (num == 2 && (b<-eps || b>eps)) cout <<"c="<<a / b;
    if (num == 2 && b>-eps&& b<eps) cout <<"Error division by zero";
   cout <<"nContinue? (1 - YES) "; cin >>n;
}       
    system("pause");
    return 0;
}

переменную с не использовал (только вывод результата) — если она нужна сообщите



1



0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 16:42

 [ТС]

12

Yetty, Спасибо, завтра попробую с этим. Сейчас времени уже нету) Если что, обращусь к вам.



0



139 / 67 / 46

Регистрация: 15.10.2015

Сообщений: 308

21.01.2018, 16:43

13

Цитата
Сообщение от Ilya-Glushko
Посмотреть сообщение

если я использую std::, не запускается

Это еще что за магия?



0



Ilya-Glushko

0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 16:43

 [ТС]

14

Reavolt,

C++
1
using namespace std;



0



139 / 67 / 46

Регистрация: 15.10.2015

Сообщений: 308

21.01.2018, 16:44

15

Ilya-Glushko, Я имел в виду то, как программа может не работать с указыванием пространства имён?



0



0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 16:46

 [ТС]

16

Reavolt, Сам задаюсь этим вопрос, штука в том, что при отсутсвии «using namespace std;» не запускается, а при присутствии и указании «std::» тоже выдает ошибку, даже на примерах из обучения.



0



139 / 67 / 46

Регистрация: 15.10.2015

Сообщений: 308

21.01.2018, 16:48

17

Ilya-Glushko, Если вы указываете пространство имен напрямую std::cout… то вам вообще не нужен using namespace std;



0



0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 16:50

 [ТС]

18

Reavolt, Указыва и убирать using namespace std; пробовал, одно и тоже.



0



7423 / 5018 / 2890

Регистрация: 18.12.2017

Сообщений: 15,694

21.01.2018, 17:25

19

Ilya-Glushko, самостоятельно добавьте в калькулятор возможность сложения, вычитания и возведения в степень (включив в программу дополнительную библиотеку #include <cmath>)



1



0 / 0 / 0

Регистрация: 21.01.2018

Сообщений: 11

21.01.2018, 17:31

 [ТС]

20

Yetty, спасибо, попробую!



0



My code is the following

int tmpCnt;  
if (name == "Dude")  
   tmpCnt++;  

Why is there an error «Use of unassigned local variable tmpCnt»?

I know I didn’t explicitly initialize it, but due to Default Value Table a value type is initialized with 0 anyway. The reference also reminds me:

Remember that using uninitialized variables in C# is not allowed.

But why do I have to do it explicitly if it’s already done by default? Wouldn’t it gain performance if I wouldn’t have to do it?

Peter Mortensen's user avatar

asked Feb 10, 2012 at 18:41

theknut's user avatar

2

Local variables aren’t initialized. You have to manually initialize them.

Members are initialized, for example:

public class X
{
    private int _tmpCnt; // This WILL initialize to zero
    ...
}

But local variables are not:

public static void SomeMethod()
{
    int tmpCnt;  // This is not initialized and must be assigned before used.

    ...
}

So your code must be:

int tmpCnt = 0;  
if (name == "Dude")  
   tmpCnt++;  

So the long and the short of it is, members are initialized, locals are not. That is why you get the compiler error.

answered Feb 10, 2012 at 18:45

James Michael Hare's user avatar

5

Default assignments apply to class members, but not to local variables. As Eric Lippert explained it in this answer, Microsoft could have initialized locals by default, but they choose not to do it because using an unassigned local is almost certainly a bug.

Community's user avatar

answered Feb 10, 2012 at 18:52

Sergey Kalinichenko's user avatar

2

The following categories of variables are classified as initially unassigned:

  • Instance variables of initially unassigned struct variables.
  • Output parameters, including the this variable of struct instance constructors.
  • Local variables , except those declared in a catch clause or a foreach statement.

The following categories of variables are classified as initially assigned:

  • Static variables.
  • Instance variables of class instances.
  • Instance variables of initially assigned struct variables.
  • Array elements.
  • Value parameters.
  • Reference parameters.
  • Variables declared in a catch clause or a foreach statement.

answered Feb 10, 2012 at 18:57

Joe's user avatar

JoeJoe

79.5k18 gold badges125 silver badges143 bronze badges

Local variables don’t have a default value.

They have to be definitely assigned before you use them. It reduces the chance of using a variable you think you’ve given a sensible value to, when actually it’s got some default value.

Peter Mortensen's user avatar

answered Feb 10, 2012 at 18:58

Damith's user avatar

DamithDamith

61.8k13 gold badges101 silver badges153 bronze badges

1

The default value table only applies to initializing a variable.

Per the linked page, the following two methods of initialization are equivalent…

int x = 0;
int x = new int();

In your code, you merely defined the variable, but never initialized the object.

answered Feb 10, 2012 at 18:46

nabrond's user avatar

nabrondnabrond

1,3508 silver badges17 bronze badges

A very dummy mistake, but you can get this with a class too if you didn’t instantiate it.

BankAccount account;
account.addMoney(5);

The above will produce the same error whereas:

class BankAccount
{
    int balance = 0;
    public void addMoney(int amount)
    {
        balance += amount;
    }
}

Do the following to eliminate the error:

BankAccount account = new BankAccount();
account.addMoney(5);

Peter Mortensen's user avatar

answered Dec 19, 2019 at 19:21

zar's user avatar

zarzar

10.9k13 gold badges91 silver badges171 bronze badges

Local variables are not automatically initialized. That only happens with instance-level variables.

You need to explicitly initialize local variables if you want them to be initialized. In this case, (as the linked documentation explains) either by setting the value of 0 or using the new operator.

The code you’ve shown does indeed attempt to use the value of the variable tmpCnt before it is initialized to anything, and the compiler rightly warns about it.

answered Feb 10, 2012 at 18:45

Cody Gray's user avatar

Cody GrayCody Gray

236k50 gold badges486 silver badges567 bronze badges

See this thread concerning uninitialized bools, but it should answer your question.

Local variables are not initialized unless you call their constructors (new) or assign them a value.

Community's user avatar

answered Feb 10, 2012 at 18:45

Msonic's user avatar

MsonicMsonic

1,45615 silver badges25 bronze badges

IEnumerable<DateTime?> _getCurrentHolidayList; //this will not initailize

Assign value(_getCurrentHolidayList) inside the loop

foreach (HolidaySummaryList _holidayItem in _holidayDetailsList)
{
                            if (_holidayItem.CountryId == Countryid)
                                _getCurrentHolidayList = _holidayItem.Holiday;                                                   
}

After your are passing the local varibale to another method like below.
It throw error(use of unassigned variable). eventhough nullable mentioned in time of decalration.

var cancelRescheduleCondition = GetHolidayDays(_item.ServiceDateFrom, _getCurrentHolidayList);

if you mentioned like below, It will not throw any error.

IEnumerable<DateTime?> _getCurrentHolidayList =null;

answered Sep 22, 2019 at 16:15

Ronika's user avatar

While value types have default values and can not be null, they also need to be explicitly initialized in order to be used. You can think of these two rules as side by side rules.

Value types can not be null → the compiler guarantees that.
If you ask how, the error message you got is the answer. Once you call their constructors, they got initialized with their default values.

int tmpCnt; // Not accepted
int tmpCnt = new Int(); // Default value applied tmpCnt = 0

Peter Mortensen's user avatar

answered Feb 10, 2012 at 18:55

Sofian Hnaide's user avatar

1

My code is the following

int tmpCnt;  
if (name == "Dude")  
   tmpCnt++;  

Why is there an error «Use of unassigned local variable tmpCnt»?

I know I didn’t explicitly initialize it, but due to Default Value Table a value type is initialized with 0 anyway. The reference also reminds me:

Remember that using uninitialized variables in C# is not allowed.

But why do I have to do it explicitly if it’s already done by default? Wouldn’t it gain performance if I wouldn’t have to do it?

Peter Mortensen's user avatar

asked Feb 10, 2012 at 18:41

theknut's user avatar

2

Local variables aren’t initialized. You have to manually initialize them.

Members are initialized, for example:

public class X
{
    private int _tmpCnt; // This WILL initialize to zero
    ...
}

But local variables are not:

public static void SomeMethod()
{
    int tmpCnt;  // This is not initialized and must be assigned before used.

    ...
}

So your code must be:

int tmpCnt = 0;  
if (name == "Dude")  
   tmpCnt++;  

So the long and the short of it is, members are initialized, locals are not. That is why you get the compiler error.

answered Feb 10, 2012 at 18:45

James Michael Hare's user avatar

5

Default assignments apply to class members, but not to local variables. As Eric Lippert explained it in this answer, Microsoft could have initialized locals by default, but they choose not to do it because using an unassigned local is almost certainly a bug.

Community's user avatar

answered Feb 10, 2012 at 18:52

Sergey Kalinichenko's user avatar

2

The following categories of variables are classified as initially unassigned:

  • Instance variables of initially unassigned struct variables.
  • Output parameters, including the this variable of struct instance constructors.
  • Local variables , except those declared in a catch clause or a foreach statement.

The following categories of variables are classified as initially assigned:

  • Static variables.
  • Instance variables of class instances.
  • Instance variables of initially assigned struct variables.
  • Array elements.
  • Value parameters.
  • Reference parameters.
  • Variables declared in a catch clause or a foreach statement.

answered Feb 10, 2012 at 18:57

Joe's user avatar

JoeJoe

79.5k18 gold badges125 silver badges143 bronze badges

Local variables don’t have a default value.

They have to be definitely assigned before you use them. It reduces the chance of using a variable you think you’ve given a sensible value to, when actually it’s got some default value.

Peter Mortensen's user avatar

answered Feb 10, 2012 at 18:58

Damith's user avatar

DamithDamith

61.8k13 gold badges101 silver badges153 bronze badges

1

The default value table only applies to initializing a variable.

Per the linked page, the following two methods of initialization are equivalent…

int x = 0;
int x = new int();

In your code, you merely defined the variable, but never initialized the object.

answered Feb 10, 2012 at 18:46

nabrond's user avatar

nabrondnabrond

1,3508 silver badges17 bronze badges

A very dummy mistake, but you can get this with a class too if you didn’t instantiate it.

BankAccount account;
account.addMoney(5);

The above will produce the same error whereas:

class BankAccount
{
    int balance = 0;
    public void addMoney(int amount)
    {
        balance += amount;
    }
}

Do the following to eliminate the error:

BankAccount account = new BankAccount();
account.addMoney(5);

Peter Mortensen's user avatar

answered Dec 19, 2019 at 19:21

zar's user avatar

zarzar

10.9k13 gold badges91 silver badges171 bronze badges

Local variables are not automatically initialized. That only happens with instance-level variables.

You need to explicitly initialize local variables if you want them to be initialized. In this case, (as the linked documentation explains) either by setting the value of 0 or using the new operator.

The code you’ve shown does indeed attempt to use the value of the variable tmpCnt before it is initialized to anything, and the compiler rightly warns about it.

answered Feb 10, 2012 at 18:45

Cody Gray's user avatar

Cody GrayCody Gray

236k50 gold badges486 silver badges567 bronze badges

See this thread concerning uninitialized bools, but it should answer your question.

Local variables are not initialized unless you call their constructors (new) or assign them a value.

Community's user avatar

answered Feb 10, 2012 at 18:45

Msonic's user avatar

MsonicMsonic

1,45615 silver badges25 bronze badges

IEnumerable<DateTime?> _getCurrentHolidayList; //this will not initailize

Assign value(_getCurrentHolidayList) inside the loop

foreach (HolidaySummaryList _holidayItem in _holidayDetailsList)
{
                            if (_holidayItem.CountryId == Countryid)
                                _getCurrentHolidayList = _holidayItem.Holiday;                                                   
}

After your are passing the local varibale to another method like below.
It throw error(use of unassigned variable). eventhough nullable mentioned in time of decalration.

var cancelRescheduleCondition = GetHolidayDays(_item.ServiceDateFrom, _getCurrentHolidayList);

if you mentioned like below, It will not throw any error.

IEnumerable<DateTime?> _getCurrentHolidayList =null;

answered Sep 22, 2019 at 16:15

Ronika's user avatar

While value types have default values and can not be null, they also need to be explicitly initialized in order to be used. You can think of these two rules as side by side rules.

Value types can not be null → the compiler guarantees that.
If you ask how, the error message you got is the answer. Once you call their constructors, they got initialized with their default values.

int tmpCnt; // Not accepted
int tmpCnt = new Int(); // Default value applied tmpCnt = 0

Peter Mortensen's user avatar

answered Feb 10, 2012 at 18:55

Sofian Hnaide's user avatar

1

Содержание

  1. C ++: ошибка C4700 используется неинициализированная локальная переменная «»
  2. Решение
  3. Другие решения
  4. Ошибка c4700 использована неинициализированная локальная переменная
  5. Проклятие неинициализированных переменных
  6. Проблема
  7. Почему ноль?
  8. Решение
  9. error c4700 использована неинициализированная локальная переменная
  10. Пример Example
  11. 1 ответ 1
  12. Компилятор не обнаруживает явно неинициализированную переменную
  13. 4 ответа:
  14. C++: ошибка C4700 неинициализированная локальная переменная «» используется
  15. ответ
  16. Область видимости переменных в C++: локальные и глобальные переменные
  17. Область видимости переменных в C++
  18. Глобальные переменные в C++
  19. Локальные переменные
  20. Глобальный оператор разрешения

C ++: ошибка C4700 используется неинициализированная локальная переменная «»

Я выписал код, но получаю сообщение об ошибке: «Ошибка неинициализированной локальной ошибки C4700« zi_saptamana ».« Неинициализированная локальная переменная ошибки C4700 «dar». Я делал вложенные If / if-else / else ранее, но никогда не сталкивался с этой ошибкой. Я новичок в C ++ и все еще учусь.

Решение

Вы заявляете zi_saptamana как int , но сразу после этого, не придав ему значения (без инициализация это ты использование это в switch заявление.

Обратите внимание, что значение zi_saptamana , которая является локальной переменной, не определена (это может быть что угодно) до ее инициализации. То же самое относится и к dar ,

Это то, что говорит вам компилятор.

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

Проще говоря (без «standardese»): это неопределенное поведение: запуск остальной части программы может зависеть от этой переменной, и если она не находится в известном состоянии, вы не можете знать, что произойдет. Вот почему большинство компиляторов помечают это как ошибку.

Другие решения

Вы должны инициализировать переменную zi_saptamana, чтобы в вашей программе работал switch, для этого просто поместите этот оператор перед switch:

он получит целочисленное значение от пользователя, и коммутатор будет работать в соответствии с этим.

Источник

Ошибка c4700 использована неинициализированная локальная переменная

Проклятие неинициализированных переменных

    Переводы, 1 февраля 2015 в 21:15

Позволять программистам использовать неинициализированные переменные — большая ошибка со стороны разработчиков языка. Такую оплошность легко совершить и тяжело отследить. Особенно при выполнении программы на разных платформах. И необходимости в этой особенности нет — переменная всегда должна иметь определенное значение.

Проблема

Локальные переменные, переменные-поля и т.п. являют собой неинициализированные переменные, т.е. в них будет записано ровно то, что было записано в отведенной под них памяти при объявлении. В C++ существуют различные правила для работы с неинициализированными переменными, инициализированными переменными и нуль-инициализированными переменными. Очень путанный механизм.

Учитывая частоту, с которой в коде появляются неинициализированные переменные, можно подумать, что отследить подобные ситуации в коде легко. Совсем нет. Да, конечно же, большая часть автоматически инициализируется нулем, если не указано иное. Однако так происходит не всегда. Например, в результате выполнения этого кода:

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

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

Почему ноль?

Почему программа автоматически инициализирует переменную нулем? На самом деле, это делает не программа, а операционная система, которая просто не позволит приложению проникнуть в неинициализированную область памяти, такова природа этого защитного механизма. Если программа A отработала свое, и результаты ее работы остались где-то в памяти, то программа B не должна обнаружить их во время своей работы, а потому ядро самостоятельно очищает память. В частности, Linux прописывает в освободившуюся память нули.

LATOKEN, Москва, от 3500 до 5000 $

Естественно, нет никакого правила, чем заполнять память. Вероятно, OpenBSD делает это как-то иначе. Иначе чистит память и ArchLinux, запущенный в VirtualBox. Этим может заниматься не только операционная система — то же может проделать и другая программа, например. И если вдруг в область памяти, которую использует приложение, попадут какие-нибудь значения, изменить их сможет уже только сама эта программа.

Любопытно, что это стало одной из причин появления Heartbleed бага.

Решение

Язык просто не должен позволять использовать неинициализированные переменные. Необязательно нужно указывать конкретное значение — значение просто обязательно должно быть. Например, значением по умолчанию может стать все тот же ноль. Вне зависимости от того, как и в какой области видимости я создал данную переменную.

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

И чтобы полностью отследить все моменты с инициализацией памяти, язык также должен иметь специальное значение noinit , которое будет показывать, что данная переменная не нуждается в инициализации.

Автор статьи уверен, что уже в ближайшем стандарте C++ должны быть реализованы эти изменения. Превращение неинициализированных ранее переменных в инициализированные не повлияет на корректность выполнения ни одной программы. Такое нововведение будет полностью backwards compatible, и серьезно улучшит популярный язык.

error c4700 использована неинициализированная локальная переменная

неинициализированная локальная переменная «имя» используется uninitialized local variable ‘name‘ used

Локальная переменная имя был используется, то есть считывание, до того, как оно было назначено значение. The local variable name has been used, that is, read from, before it has been assigned a value. В C и C++ локальные переменные не инициализируются по умолчанию. In C and C++, local variables are not initialized by default. Неинициализированные переменные могут содержать любое значение, и их применение приводит к неопределенному поведению. Uninitialized variables can contain any value, and their use leads to undefined behavior. Предупреждение C4700 почти всегда указывает на ошибку, что может привести к непредсказуемым результатам или происходит аварийный сбой программы. Warning C4700 almost always indicates a bug that can cause unpredictable results or crashes in your program.

Чтобы устранить эту проблему, можно инициализировать локальные переменные, если они объявлены, или назначить значение к ним, прежде чем они используются. To fix this issue, you can initialize local variables when they are declared, or assign a value to them before they are used. Функция может использоваться для инициализации переменной, передаваемый в качестве ссылочного параметра, или если адрес передается как параметр-указатель. A function can be used to initialize a variable that’s passed as a reference parameter, or when its address is passed as a pointer parameter.

Пример Example

Этот пример приводит к возникновению ошибки C4700, когда переменные t, u и v используются, прежде чем они инициализируются и показывает, какие значения сборки мусора, которая может привести. This sample generates C4700 when variables t, u, and v are used before they are initialized, and shows the kind of garbage value that can result. Переменные x, y и z не вызвать предупреждение, так как они инициализируются перед использованием: Variables x, y, and z do not cause the warning, because they are initialized before use:

Когда этот код является выполнения, t, u и v не инициализированы и выходные данные для s будет непредсказуемым: When this code is run, t, u, and v are uninitialized, and the output for s is unpredictable:

Не могу запустить рабочий проект под Visual Studio 2013 из-за этой ошибки. Проект старый, делался еще под Visual Studio 6.0. Видимо, там выдавалось предупреждение вместо ошибки.

Переменных много. Может быть, все-таки можно обойти эту ошибку, не инициализируя их все?

1 ответ 1

В свойствах проекта — свойства конфигурации — С/С++ — создание кода — проверка безопасности — Отключить проверку безопасности (/GS-)

Здравствуйте. Я совсем новичок в программировании, никакого опыта не было. В общем компилятор показывает ошибку «error C4700: использована неинициализированная локальная переменная «a» и также «b». Не могу понять, что нужно сделать, укажите пожалуйста на ошибку.

  • Вопрос задан более трёх лет назад
  • 16829 просмотров

Вы складываете a и b, не присвоив им значений. В C/C++ в этом случае в переменных может оказаться произвольный мусор. Нужно писать double a = 0; double b = 0;

Компилятор не обнаруживает явно неинициализированную переменную

все компиляторы C, которые я пробовал, не будут обнаруживать неинициализированные переменные в приведенном ниже фрагменте кода. Тем не менее, случай здесь очевиден.

не беспокойтесь о функциональности этого фрагмента. Это не настоящий код, и я снял его для расследования этого вопроса.

С другой стороны, если я закомментировать tauxtrouve = value ; , Я «local variable ‘tauxtrouve’ used without having been initialized» предупреждение.

Я пробовал эти компиляторы:

  • GCC 4.9.2 с -стена -WExtra
  • Microsoft Visual C++ 2013 со всеми включенными предупреждениями

4 ответа:

очевидности, с которой эта переменная не инициализируется завышена. Анализ пути стоит времени, и ваши поставщики компиляторов либо не хотели реализовывать эту функцию, либо думали, что это будет стоить вам слишком много времени, или вы просто не выбрали явно.

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

EDIT: @Matthieu указывает, что с LLVM/clang анализ пути, необходимый для поиска использования неинициализированного значения, не усложняется по мере увеличения вложенности из-за нотации SSA, используемой IR.

это не так просто, как » -S -emit-llvm » как я надеялся, но я нашел выход SSA-нотации, который он описал. Я буду честен, я недостаточно знаком с LLVM IR, чтобы быть уверенным, но я поверю Матье на слово.

итог: использовать clang С —analyze , или убедить кого-то, чтобы исправить gcc ошибка.

Да, это должно вызвать предупреждение об этой неинициализированной переменной, но это ошибка GCC. Приведенный там пример:

с диагнозом -O2 -W -Wall .

к сожалению, в этом году 10-летний юбилей этой ошибки!

этот ответ касается только GCC.

после дальнейшего расследования и комментариев, происходит больше, чем в моем предыдущем ответе. Этот фрагмент кода имеет две неинициализированные переменные, и каждая из них не обнаружена по другой причине.

прежде всего,документация GCC на говорит:

поскольку эти предупреждения зависят от оптимизации, точных переменных или элементов, для которых существуют предупреждения зависит от точных параметров оптимизации и используемой версии GCC.

предыдущие версии руководства GCC сформулировали это более явно. Вот отрывок из руководство для GCC 3.3.6:

эти предупреждения возможны только при оптимизации компиляции, поскольку они требуют информации о потоке данных, которая вычисляется только при оптимизации. Если вы не укажете-O, вы просто не получите эти предупреждения.

It кажется, текущая версия может дать некоторые предупреждения без неинициализированных переменных без -O , но вы все равно получите гораздо лучшие результаты с ним.

если я скомпилирую ваш пример с помощью gcc -std=c99 -Wall -O , Я:

(обратите внимание, что это с GCC 4.8.2, поскольку у меня нет 4.9.x установлен, но принцип должен быть таким же.)

так, что обнаруживает тот факт, что tauxtrouve инициализирован.

однако, если мы частично исправим код, добавив инициализатор для tauxtrouve (но не totaldiff ), то gcc -std=c99 -Wall -O принимает его без каких-либо предупреждений. Это, по-видимому, является экземпляром» ошибки», приведенной в haccks это.

есть некоторые вопросы относительно того, следует ли это действительно считать ошибкой: GCC не обещает поймать каждый возможный экземпляр неинициализированной переменной. Действительно, он не может сделать это с идеальной точностью, потому что это проблема останова. Поэтому такие предупреждения могут быть полезны, когда они работают, но отсутствие предупреждений не доказывает, что ваш код свободен от неинициализированных переменных! Они действительно не являются заменой для тщательной проверки Вашего собственного кода.

на отчет об ошибке, связанный с haccks, существует много дискуссий о том, является ли ошибка даже исправимой, или попытка обнаружить эту конкретную конструкцию приведет к неприемлемой ложной положительной скорости для другого правильного кода.

Майкл, я не знаю, какую версию Visual Studio 2013 Вы пробовали, но она, безусловно, устарела. Visual Studio 2013 Update 4 правильно выдает следующее сообщение об ошибке при первом использовании totaldiff :

вы должны рассмотреть возможность обновления рабочей среды.

C++: ошибка C4700 неинициализированная локальная переменная «» используется

Я выписал код, но я все время получаю сообщение об ошибке: «Использована неинициализированная локальная переменная Error C4700« zi_saptamana ». Ошибка C4700 неинициализированной локальной переменной« dar ». Я уже делал If/if-else/else, но я никогда не сталкивался с этой ошибкой. Я новичок в C++ и все еще учась.C++: ошибка C4700 неинициализированная локальная переменная «» используется

Ошибка довольно сам пояснительный. Я имею в виду, что из кода ‘zi_saptamana’ не был инициализирован код’ switch (zi_saptamana) ‘ – drescherjm

Какая часть« неинициализированной локальной переменной используется »неясно? –

Сообщение об ошибке ясно. Когда ‘switch (zi_saptamana)’, ‘zi_saptamana’ не инициализируется или не задается, его значение неопределенно. – songyuanyao

ответ

Вы объявляете zi_saptamana в int , но сразу после этого, не давая ему значение (без инициализации его), вы использование это в switch заявлении.

Обратите внимание, что значение zi_saptamana , которое является локальной переменной, не определено (оно может быть любым) перед его инициализацией. То же самое относится к dar .

Это то, что говорит вам компилятор.

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

Проще говоря (без «стандартного»): это неопределенное поведение: запуск остальной части программы может зависеть от этой переменной, и если она не находится в известном состоянии, вы не можете знать, что будет бывает. Вот почему большинство компиляторов отмечают это как ошибку.

Это не то, что «может быть что угодно», это то, что чтение неинициализированной переменной является неопределенным поведением, поэтому программа не имеет никакого смысла, и компилятор может что-либо сделать, включая удаление полностью выключайте. Вам не гарантируется просто получить случайную величину мусора (хотя вы * можете *). –

Ну, для всех, кого вы знаете или заботитесь, это может быть что угодно. Именно поэтому использование неинициализированной переменной было объявлено как неопределенное поведение, ISTM. –

Ну, компиляторы довольно агрессивно относятся к использованию неопределенного поведения в наши дни. И это может изменить другие части вашей программы, а также результат — вы не можете предположить, что «эффекты неопределенности» будут содержаться в * просто * взаимодействиях с одной переменной. См. Например [this] (https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=633), [это] (http://blog.regehr.org/archives/213) & [это] (http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html). –

Вы должны инициализировать переменную zi_saptamana иметь переключатель работает в вашей программе, чтобы сделать это просто поставить это заявление перед переключателем: —

он будет принимать значение целого числа от пользователя и переключатель будет работать в соответствии к этому.

Область видимости переменных в C++: локальные и глобальные переменные

Всем привет! Сегодня мы затронем тему, которую должны были изучить еще в самом начале пути изучения C++ — область видимости переменных. Мы разберем, что такое локальные и глобальные переменные.

Область видимости переменных в C++

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

В C++ существуют отдельные блоки, которые начинаются с открывающей скобки ( ). Такими блоками являются циклы (for, while, do while) и функции.

В примере ниже, программист ошибся с областью видимости:

  • Он создал переменную j во втором цикле.
  • Использовав ее в первом цикле for он вынудил компилятор сообщить об ошибке (переменной j больше нет, поскольку второй цикл закончил свою работу).

Глобальные переменные в C++

Глобальными переменными называются те переменные, которые были созданы вне тела какого-то блока. Их можно всегда использовать во всей вашей программе, вплоть до ее окончания работы. В примере ниже мы создали две глобальные переменные global и global_too и использовали их в функции summa :

Локальные переменные

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

Из этого можно сделать вывод: у нас есть возможность создавать переменные с одинаковыми именами, но в разных блоках (или другими словами, чтобы их область видимости не совпадала друг с другом).

Распространенной ошибкой среди начинающих программистов является использование локальных переменных в других блоках. Например ниже мы решили использовать переменную cost в функции summa , хотя мы ее создали в совершенно другой функции — main .

А вот, если мы вызовем функцию sait_message то результатом будет:

Вот так глобальная переменная уступает локальной!

Мы советуем вам не создавать переменные с одинаковыми именами, поскольку в будущем вам будет тяжело разобраться в коде, если там будут присутствовать одинаковые переменные.

Глобальный оператор разрешения

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

Глобальный оператор разрешения — это два подряд поставленные двоеточия, с помощью которых мы говорим компилятору, что хотим использовать глобальную переменную, а не локальную.

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

Источник

Имеется код:

Source.cpp

#include "Header.h"
int main() {
    srand(time(0));
    int n = 3;
    int m = 3;
    int maxi;
    int maxj;
    int** Mas ;
    int** Bufer ;
    initMemory(Mas , n, m);
    initMemory(Bufer ,n, m);
    Zapoln(Mas, n, m);
    cout << "Massive: " << endl;
    vyvod(Mas, n, m);
    Masscopy(Bufer, Mas, n, m);
    cout << "Copy of massive: " << endl;
    vyvod(Bufer , n, m);
    freeMemory(Mas, n);
    initMemory(Mas, n - 1, m - 1);
    int max = maxel(Bufer, n, m, maxi, maxj);
    cout << endl;
    cout << "Max element: " << "[" << maxi << "]" << "[" << maxj << "]" << "=" << max << endl;
    cout << endl;
    del(Bufer, maxi, maxj, n, m);
    vozvr(Mas, Bufer , n -1 , m -1);
    cout << "After massive: " << endl;
    vyvod(Mas, n - 1, m - 1);
    freeMemory(Bufer, n);
    delete[] Bufer;
    system("pause");
}

memory.cpp

#include "Header.h"
void initMemory(int **A, int n, int m) {
    A = new int *[n];
    for (int i = 0; i < n; i++) {
        A[i] = new int[m];
    }
}
void freeMemory(int **A, int n) {
    for (int i = 0; i < n; i++) {
        delete[] A[i];
    }
}

Array_helper.cpp

#include "Header.h"
void vyvod(int **A, int n, int m) {
    for (int i = 0; i< n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cout << "mas[" << i << "]" << "[" << j << "]=" << setprecision(3) << *(*(A + i) + j) << " ";
        }
        cout << endl;
    }
}
void Zapoln(int **A, int n, int m) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            *(*(A + i) + j) = rand() % 26 - rand() % 26;
        }
    }
}
void Masscopy(int** A, int** B, int n, int m) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            *(*(A + i) + j) = *(*(B + i) + j);
        }
    }
}

void del(int **A, int  maxi, int maxj, int n, int m) {
    for (int i = maxi; i < n - 1; i++) {
        for (int j = maxj; j < m - 1; j++) {
            *(*(A + i) + j) = *(*(A + i + 1) + j + 1);
        }
    }
}

Logic.cpp

#include "Header.h"
void vozvr(int** A, int** B, int n, int m) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            *(*(A + i) + j) = *(*(B + i) + j);
        }
    }
}
int maxel(int **A, int n, int m, int& maxi, int& maxj)
{
    int Max = A[0][0];
    maxi = maxj = 0;
    for (int i = 0; i< n; i++)
        for (int j = 0; j< m; j++)
            if (fabs(A[i][j]) > fabs(Max))
            {
                Max = fabs(*(*(A + i) + j));
                maxi = i;
                maxj = j;
            }
    return Max;
}

Однако при выполнении выдает ошибку:

  • 1>d:загрузкиsource.cpp(10): error C4700: использована
    неинициализированная локальная переменная «Mas»
    1>d:загрузкиsource.cpp(11): error C4700: использована
    неинициализированная локальная переменная «Bufer»

В чём проблема?

Добавлено 8 апреля 2021 в 17:40

Неинициализированные переменные

В отличие от некоторых языков программирования, C/C++ не инициализирует большинство переменных автоматически заданным значением (например, нулем). Таким образом, когда компилятор выделяет переменной место в памяти, значением по умолчанию для этой переменной является любое (мусорное) значение, которое уже находится в этой области памяти! Переменная, которой не было присвоено известное значение (обычно посредством инициализации или присваивания), называется неинициализированной переменной.

Примечание автора


Многие читатели ожидают, что термины «инициализированный» и «неинициализированный» будут строго противоположными, но это не совсем так! Инициализация означает, что объекту было предоставлено начальное значение в точке определения. Неинициализированный означает, что объекту не было присвоено известное значение (каким-либо образом, включая присваивание). Следовательно, объект, который не инициализирован, но которому затем было присвоено значение, больше не является неинициализированным (потому что ему было присвоено известное значение).

Резюмируем:

  • инициализация = объекту присваивается известное значение в точке определения;
  • присваивание = объекту присваивается известное значение в точке, выходящей за рамки определения;
  • неинициализированный = объекту еще не присвоено известное значение.

В качестве отступления…


Отсутствие инициализации является оптимизацией производительности, унаследованной от C, когда компьютеры были медленными. Представьте себе случай, когда вы собираетесь прочитать 100 000 значений из файла. В таком случае вы можете создать 100 000 переменных, а затем заполнить их данными из файла.

Если бы C++ инициализировал все эти переменные при создании значениями по умолчанию, это привело бы к 100 000 инициализаций (что было бы медленно) и к небольшой выгоде (поскольку вы всё равно перезапишете эти значения).

На данный момент вы всегда должны инициализировать свои переменные, потому что затраты на это ничтожны по сравнению с выгодой. Как только вы освоите язык, тогда могут быть определенные случаи, когда вы можете пропустить инициализацию в целях оптимизации. Но делать это всегда нужно выборочно и намеренно.

Использование значений неинициализированных переменных может привести к неожиданным результатам. Рассмотрим следующую короткую программу:

#include <iostream>
 
int main()
{
    // определяем целочисленную переменную с именем x
    int x; // эта переменная не инициализирована, потому что мы не присвоили ей значение
    
    // выводим значение x на экран
    std::cout << x; // кто знает, что мы получим, потому что x не инициализирована
 
    return 0;
}

В этом случае компьютер выделит для x некоторую неиспользуемую память. Затем он отправит значение, находящееся в этой ячейке памяти, в std::cout, который напечатает значение (интерпретируемое как целое число). Но какое значение он напечатает? Ответ – «кто знает!», и ответ может (или не может) меняться каждый раз, когда вы запускаете программу. Когда автор запускал эту программу в Visual Studio, std::cout в первый раз вывел значение 7177728, а во второй раз – 5277592. Не стесняйтесь компилировать и запускать программу самостоятельно (ваш компьютер не взорвется).

В качестве отступления…


Некоторые компиляторы, такие как Visual Studio, при использовании конфигурации отладочной сборки будут инициализировать содержимое памяти некоторым предустановленным значением. Этого не произойдет при использовании конфигурации сборки выпуска. Поэтому, если вы хотите запустить указанную выше программу самостоятельно, убедитесь, что вы используете конфигурацию сборки выпуска (чтобы вспомнить, как это сделать, смотрите урок «0.9 – Настройка компилятора: конфигурации сборки»). Например, если вы запустите приведенную выше программу в конфигурации отладки в Visual Studio, она будет неизменно печатать -858993460, потому что с помощью этого значения (интерпретируемого как целое число) Visual Studio инициализирует память в конфигурациях отладки.

Большинство современных компиляторов пытаются определить, используется ли переменная без присваивания значения. Если они смогут это обнаружить, они обычно выдадут ошибку времени компиляции. Например, компиляция приведенной выше программы в Visual Studio выдала следующее предупреждение:

c:VCprojectstesttest.cpp(11) : warning C4700: uninitialized local variable 'x' used

Если ваш компилятор по этой причине не позволяет вам скомпилировать и запустить приведенную выше программу, вот возможное решение этой проблемы:

#include <iostream>

// Пока не беспокойтесь о том, что такое &, мы просто используем его, 
// чтобы заставить компилятор думать, что переменная x используется 
void doNothing(int&) 
{
}
 
int main()
{
    // определяем целочисленную переменную с именем x
    int x; // эта переменная не инициализирована
 
    // заставляем компилятор думать, что мы присваиваем значение этой переменной
    doNothing(x);
 
    // выводим значение x на экран (кто знает, что мы получим, потому что x не инициализирован)
    std::cout << x;
 
    return 0;
}

Использование неинициализированных переменных – одна из наиболее распространенных ошибок, которые совершают начинающие программисты, и, к сожалению, она также может быть одной из самых сложных для отладки (потому что программа всё равно может работать нормально, если неинициализированное значение было присвоено определенной области памяти, которая содержала приемлемое значение, например, 0).

Это основная причина использования оптимальной практики «всегда инициализировать переменные».

Неопределенное поведение

Использование значения из неинициализированной переменной – наш первый пример неопределенного поведения. Неопределенное поведение – это результат выполнения кода, поведение которого не определено языком C++. В этом случае в языке C++ нет правил, определяющих, что произойдет, если вы используете значение переменной, которой не было присвоено известное значение. Следовательно, если вы действительно сделаете это, результатом будет неопределенное поведение.

Код, реализующий неопределенное поведение, может проявлять любые из следующих симптомов:

  • ваша программа при каждом запуске дает разные результаты;
  • ваша программа постоянно дает один и тот же неверный результат;
  • ваша программа ведет себя непоследовательно (иногда дает правильный результат, иногда нет);
  • кажется, что ваша программа работает, но позже выдает неверные результаты;
  • ваша программа вылетает сразу после запуска или позже;
  • ваша программа работает с одними компиляторами, но не работает с другими;
  • ваша программа работает до тех пор, пока вы не измените какой-нибудь другой, казалось бы, несвязанный код.

Или ваш код в любом случае может действительно вести себя правильно. Природа неопределенного поведения заключается в том, что вы никогда не знаете точно, что получите, будете ли вы получать это каждый раз, и изменится ли это поведение, когда вы внесете какие-либо изменения.

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

Правило


Старайтесь избегать всех ситуаций, которые приводят к неопределенному поведению, например, использование неинициализированных переменных.

Примечание автора


Один из наиболее распространенных типов комментариев, которые мы получаем от читателей, гласит: «Вы сказали, что я не могу делать X, но я всё равно сделал это, и моя программа работает! Почему?».

Есть два общих ответа. Наиболее распространенный ответ заключается в том, что ваша программа на самом деле демонстрирует неопределенное поведение, но это неопределенное поведение в любом случае дает желаемый результат… пока. Завтра (или на другом компиляторе или машине) этого может и не быть.

В качестве альтернативы, иногда авторы компиляторов допускают вольность к требованиям языка, когда эти требования могут быть более строгими, чем необходимо. Например, в стандарте может быть сказано: «Вы должны сделать X перед Y», но автор компилятора может счесть это ненужным и заставить Y работать, даже если вы сначала не выполните X. Это не должно влиять на работу правильно написанных программ, но в любом случае может привести к тому, что неправильно написанные программы будут работать. Таким образом, альтернативный ответ на вышеупомянутый вопрос заключается в том, что ваш компилятор может просто не следовать стандарту! Такое случается. Вы можете избежать этого, если отключили расширения компилятора, как описано в уроке «0.10 – Настройка компилятора: расширения компилятора».

Небольшой тест


Вопрос 1

Что такое неинициализированная переменная? Почему вам следует избегать их использования?

Ответ

Неинициализированная переменная – это переменная, которой программа не присвоила значение (обычно посредством инициализации или присваивания). Использование значения, хранящегося в неинициализированной переменной, приведет к неопределенному поведению.


Вопрос 2

Что такое неопределенное поведение и что может произойти, если вы сделаете что-то, что демонстрирует неопределенное поведение?

Ответ

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

Теги

C++ / CppLearnCppДля начинающихОбучениеПрограммирование

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Исполнительское мастерство актера достойно восхищения речевая ошибка
  • Испортила вещь отбеливателем как исправить
  • Испортил девушке настроение как исправить
  • Исполнитель получает вечный доступ к заданиям перепишите предложение исправив орфографические ошибки
  • Используя языковые средства выразительности текст выглядит более убедительным где ошибка

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии