description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Learn more about: Compiler Warning (level 1 and level 4) C4700 |
Compiler Warning (level 1 and level 4) C4700 |
08/30/2022 |
C4700 |
C4700 |
2da0deb4-77dd-4b05-98d3-b78d74ac4ca7 |
uninitialized local variable ‘name‘ used
Remarks
The local variable name has been used, that is, read from, before it has been assigned a value. In C and C++, local variables aren’t initialized by default. Uninitialized variables can contain any value, and their use leads to undefined behavior. 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’re declared, or assign a value to them before they’re 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.
The /sdl
(Enable Additional Security Checks) compiler option elevates this warning to an error.
Example
This sample generates C4700 when variables t
, u
, and v
are used before they’re initialized, and shows the kind of garbage value that can result. Variables x
, y
, and z
don’t cause the warning, because they’re initialized before use:
// c4700.cpp // compile by using: cl /EHsc /W4 c4700.cpp #include <iostream> // function takes an int reference to initialize void initialize(int& i) { i = 21; } int main() { int s, t, u, v; // Danger, uninitialized variables s = t + u + v; // C4700: t, u, v used before initialization std::cout << "Value in s: " << s << std::endl; int w, x; // Danger, uninitialized variables initialize(x); // fix: call function to init x before use int y{10}; // fix: initialize y, z when declared int z{11}; // This C++11 syntax is recommended over int z = 11; w = x + y + z; // Okay, all values initialized before use std::cout << "Value in w: " << w << std::endl; }
When this code is run, t
, u
, and v
are uninitialized, and the output for s
is unpredictable:
Value in s: 37816963
Value in w: 42
When I compile this code it says «error C4700: uninitialized local variable ‘b’ used». I’m not sure what I have to do now to fix this problem. I’m neither an IT student or technican but I very like to learn C++ and I’m learning it by myself. I’ve been on this for 1 day.
Many thanks
#include <stdio.h>
#include <iostream>
//A.
//1--
void InputArray(int *a, int &n)
{
printf("Insert n = ");
scanf("%d", &n);
a = new int[n];
for (int i=0; i<n; i++)
{
printf("Enter the key's a[%d] values: ", i);
scanf("%d",&a[i]);
}
}
void main()
{
int *b, m;
InputArray(b, m);
}
BennX
6,1743 gold badges36 silver badges85 bronze badges
asked Feb 20, 2014 at 19:18
2
b
is passed by value, which means a copy will be made, but since it’s not initialized, you get the warning. Simply initialize it:
int *b = nullptr;
or
int *b = NULL;
answered Feb 20, 2014 at 19:21
Luchian GrigoreLuchian Grigore
251k63 gold badges454 silver badges619 bronze badges
0
If you want the function to modify the caller’s variable, then pass by reference:
void InputArray(int *&a, int &n)
^
Your version passes the uninitialised pointer by value; the function modifies a local copy of it, but leaves b
in its uninitialised state.
answered Feb 20, 2014 at 19:19
Mike SeymourMike Seymour
247k28 gold badges442 silver badges638 bronze badges
3
The pointers are not default initialized, so your variable b
is uninitialized, this is the source of error. You have to initialize this variable to fix this:
void main()
{
int *b = NULL, m;
InputArray(b, m);
}
After you fix this there is additional problem in your code. It seems from the way you call a function that you expect to persistently change pointer b
passed into it, so that b
will point into memory allocated with new
after function returned. But you pass a pointer by value what means changes made in function will not be reflected in original variable b
which will still point to what it pointed before the call to a function. (the array will be allocated inside function and will stay in memory after function returned but you will leak this memory as b
won’t point into it). To fix this you have to pass pointer by reference:
void InputArray(int*& a, int& n)
Also: where is delete
? Remember: mapping new
to delete
is bijection: every new
corresponds to single delete
placed somewhere in code.
answered Feb 20, 2014 at 19:22
4pie04pie0
29k9 gold badges81 silver badges118 bronze badges
2
First of all, did you learn how to use an pointer correctly ? because if you know how to use pointer u should know that when you declare a pointer you need to be initialized to NULL before you can use it, correct me if i’m wrong.
Example
int *b = nullptr;
int *b = NULL;
int *b = 0;
int *b(0);
It’s all the same thing but in an different way
answered Jan 2, 2017 at 17:41
1
Дообрый день! Имеется следующий код
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <conio.h>
using namespace std;
double count(double, double, double, double);
void input(void);
void output(void);
int main()
{
double a, b, c, d, y;
input();
y = count(a, b, c, d);
output();
double count (double a, double b, double c, double d) {
return 2 * sqrt((sin(a) / fabs(tan(b - a)) + (log(c) / d)));
}
void input(void) {
cout << "Enter a" << endl;
cin >> a;
cout << "Enter b" << endl;
cin >> b;
cout << "Enter c" << endl;
cin >> c;
cout << "Enter d" << endl;
cin >> d;
}
void output(void) {
cout << "Your y is " << y;
}
_getch();
return 0;
}
При компиляции выскакивают ошибки:
Error C4700 uninitialized local variable ‘a’ used
Error C4700 uninitialized local variable ‘b’ used
Error C4700 uninitialized local variable ‘c’ used
Error C4700 uninitialized local variable ‘d’ used
Прдскажите, пожалуйста, в чем проблема.. не могу понять.. переменные же вроде инициализировала еще в самом начале функции main()
artem_xapbkoB 0 / 0 / 0 Регистрация: 26.11.2015 Сообщений: 26 |
||||
1 |
||||
26.11.2015, 17:49. Показов 5530. Ответов 7 Метки нет (Все метки)
1>c:usersартемdocumentsvisual studio 2012projectsconsoleapplication37source.cpp(7): warning C4700: uninitialized local variable ‘pipes’ used выдает ошибку
__________________
0 |
nocl1p 55 / 38 / 20 Регистрация: 30.03.2012 Сообщений: 330 |
||||||||
26.11.2015, 17:54 |
2 |
|||||||
Сообщение было отмечено artem_xapbkoB как решение РешениеПрисвойте этим переменным значения например 0 при ее создании
Добавлено через 1 минуту
0 |
3985 / 3255 / 909 Регистрация: 25.03.2012 Сообщений: 12,102 Записей в блоге: 1 |
|
26.11.2015, 18:02 |
3 |
artem_xapbkoB, warning это не ошибка. Ты вообще не туда смотришь. Глаза разуй.
0 |
55 / 38 / 20 Регистрация: 30.03.2012 Сообщений: 330 |
|
26.11.2015, 18:05 |
4 |
Студия выстрелит ошибку уже в процессе работы программы при не инициализированных переменных. Добавлено через 1 минуту
0 |
0 / 0 / 0 Регистрация: 26.11.2015 Сообщений: 26 |
|
26.11.2015, 18:29 [ТС] |
5 |
ну так помогите переделать код?)
0 |
nocl1p 55 / 38 / 20 Регистрация: 30.03.2012 Сообщений: 330 |
||||
26.11.2015, 18:38 |
6 |
|||
0 |
0 / 0 / 0 Регистрация: 26.11.2015 Сообщений: 26 |
|
26.11.2015, 18:52 [ТС] |
7 |
вот мне нужно сделать через принт и сканф
0 |
Kuzia domovenok 3985 / 3255 / 909 Регистрация: 25.03.2012 Сообщений: 12,102 Записей в блоге: 1 |
||||
26.11.2015, 19:01 |
8 |
|||
0 |
- Remove From My Forums
-
Question
-
I made a blanket balance checking program like following.
This code worrks well.
#include <iostream> #include <string> #include <stack> using namespace std; bool openblaket(char c) { bool ret; if (c == '{' || c == '[' || c == '(') ret = true; else ret = false; return(ret); } bool MatchBlanket(char c1, char c2) { if (c1 == '{' && c2 == '}') return true; if (c1 == '[' && c2 == ']') return true; if (c1 == '(' && c2 == ')') return true; return false; } bool IsBalanced(string s) { bool ret = true; stack<char>* mystack = new stack<char>; int n = s.length(); char* char_array = new char[n + 1]; strcpy(char_array, s.c_str()); for (int i = 0; i < n; i++) { if (openblaket(char_array[i])) mystack->push(char_array[i]); else if (MatchBlanket(mystack->top(),char_array[i]) == true) mystack->pop(); } if (mystack->size() > 0) ret = false; delete mystack; mystack = NULL; delete[] char_array; char_array = NULL; return(ret); } int main() { string s = "{[()]}"; if (IsBalanced(s)) cout << "balanced!"; else cout << "Not balanced!"; }
However, if I make stack in stack memory instead of heap memory like following, error occur.
stack<char>* mystack
Error C4700 Uninitialized local variable 'mystack' used
Why should I create mystack only in heap?
Answers
-
Creating on the stack would be
stack<char> mystack;
without the star. Then you’d have to replace all mystack->something with mystack.something.
Igor Tandetnik
-
Marked as answer by
Monday, April 13, 2020 2:41 AM
-
Marked as answer by
-
stack<char>* mystack
Error C4700 Uninitialized local variable 'mystack' used
Why should I create mystack only in heap?
This code declares a pointer variable. The pointer is uninitialized.
If you want an object on the stack then use.
stack<char> mystack;
-
Edited by
RLWA32
Sunday, April 12, 2020 9:43 PM -
Marked as answer by
Jeff0803
Monday, April 13, 2020 2:42 AM
-
Edited by
- Forum
- General C++ Programming
- Error «C4700: uninitialized local variab
Error «C4700: uninitialized local variable»
Hello people, this is my first time using this site so cut me some slack if I have trouble. I am in currently Foundations and Computer Programming II learning how to use C++ in more advance ways. I been given my first assignment and I’ve already came across an error that I don’t know how to fix. The error is «C4700: uninitialized local variable ‘n2’ used» and here is what I have.
main.cpp
|
|
multiply.h
void multiply(int, int);
multiply.cpp
|
|
Can anyone please help me figure out what I am doing wrong.
Last edited on
Thank you for that tip Tarik, but now I have come across 2 more errors when I made that change. Both of them are error «LNK2019: unresolved external symbol.»
One error says ‘WinMain@16 referenced in function «int_cdel invoke_main(void)» (? invoke_main@@YAHXZ)’
The other one says ‘»void_decl multiply(int,int)» (?multiply@@YAXHH@Z) referenced in function_main’
I think this might be more of a file error, but I’m not sure. I should probably start another forum.
I should probably start another forum.
What does that even mean?
Your problem is simple, your function prototype and your function definition do not look idenetical, which they have to.
void multiply(int, int); // takes 2 integers
void multiply(int& n1, int n2) // takes 2 integers, but the first one by reference
They have to look the same.
void multiply(int& n1, int n2); // change your function that is in multiply.h to this
Well there goes one of the errors. But the first one is still there.
‘WinMain@16 referenced in function «int_cdel invoke_main(void)» (? invoke_main@@YAHXZ)’
Last edited on
This means that you’ve selected the wrong kind of project. You’re using Visual Studio version something; if you want to use a main function, you needed to create a simple, plain console project.
Topic archived. No new replies allowed.
Содержание
- Error c4700 uninitialized local variable
- Error c4700 uninitialized local variable
- Answered by:
- Question
- Answers
- All replies
- Error c4700 uninitialized local variable
Error c4700 uninitialized local variable
My issue is i am getting error C4700: uninitialized local variable ‘response’ used on line 26. I know it’s probably something simple I’m completely missing please help.
Here’s my instructions:
The local Driver’s License Office has asked you to write a program which grades the written portion of the driver’s license exam. The exam has 20 multiple choice questions. The correct answers are:
1. A 2. D 3. B 4. B 5. C 6. B 7. A 8. B 9. C 10. D 11. A 12. C 13. D 14. B 15. D 16. C 17. C 18. A 19. D 20. B
In main, declare an array and initialize it with the above correct answers. Also declare a second array for an exam taker’s answers, and get a text file name from the user.
This program will have two functions:
1) have the user enter 20 answers from an exam taker and write the answers to the text file (validate that the answers are A, B, C, or D). See the 20 exam taker’s answers below.
Hint: open (and close) the file in the function.
2) read the text file of the exam taker’s answers and store them in the exam taker’s array, which was declared in main.
Then in main, the program should display the following information:
-whether the exam taker passed or failed (15 of the 20 answers must be correct).
-total number of questions answered correctly
-total number of questions answered incorrectly
-a list of the numbers of the questions answered incorrectly (question numbers are 1-20).
Источник
Error c4700 uninitialized local variable
This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.
Answered by:
Question
I created a infix to postfix converter. Below is the code:
// pstcnvrtr.cpp : Converts infix notation to postfix.
//Author: Evolution; Date: 9 Feb 2013 Time:9:17pm
#include
#include
using namespace std;
int priority(char );
void main()
<
char *stack,*symbol,*post,*temp;
int top=-1,len,psym,pstk;
cout top=top+1;
stack[top]='(‘;
stack[top+1]=’′;
>
else if(*symbol==’^’||*symbol==’/’||*symbol==’*’||*symbol==’+’||*symbol==’-‘)
<
psym=priority(*symbol);
pstk=priority(stack[top]);
while(psym <
*post=stack[top];
top—;
stack[top+1]=’′;
post++;
*post=’′;
pstk=priority(stack[top]);
>
top=top+1;
stack[top]=*symbol;
stack[top+1]=’′;
>
else if(*symbol==’)’)
<
while(stack[top]!='(‘)
<
*post=stack[top];
top—;
stack[top+1]=’′;
post++;
*post=’′;
>
top—;
stack[top+1]=’′;
>
else
<
*post=*symbol;
post++;
*post=’′;
>
symbol++;
>
post=temp;
cout
Answers
Also if I follow one of your methods and declare the arrays like this:
Then I meet a series of errors which makes the entire code to be modified. The errors are listed below:
Error 1 error C2106: ‘=’ : left operand must be l-value
Error 6 error C2106: ‘=’ : left operand must be l-value
Error 2 error C2105: ‘++’ needs l-value
Error 3 error C2105: ‘++’ needs l-value
Error 4 error C2105: ‘++’ needs l-value
Error 5 error C2105: ‘++’ needs l-value
You should probably change the code to something like:
Also, post needs to be initialized. I don’t understand this algorithm well enough to tell you how it needs to be initialized; it doesn’t make sense to me.
As a final comment, if you are going to program in C or C++, you need a basic understanding of pointers and arrays before you can move forward. It’s clear from your post that you are confused over these fundamental concepts.
This material is covered in every introductory C or C++ textbook. I suggest you re-read this material, or Google/Bing for «pointers arrays C» and a number of tutorials will pop up.
Look at this little snippet of code. You create a variable called stack. Stack is will point to memory that contains a sequence of chars. But you never told it where to point. You then decide to poke ‘(‘ at that (undefined) memory location. The compiler sees this and emits the warning you are seeing.
If this code worked for you under Turbo C, then it was simply a fluke that it did.
You need to provide storage for the memory that you are writing. There are a number of ways to do it. The most fundamental way (but not really recommended in modern C++) would be to use new to allocate a buffer, the delete to free it
Another option is to put it on the stack. This option is probably the simplest, and works well if you know in advance how large your buffers need to be and they are relatively small.
The more modern C++ way to tackle something like this would be:
I very clearly understand what the error is all about
The same fundamental programming error occurs with variables
«post» and «symbol»:
. // «symbol» never assigned a value
>gets_s(symbol,20); // storing at a random address
As «post» has never been assigned a value, you’re storing
a random value in «temp».
I tried assigning null string to all the undeclared strings as below:
This of course removed all the errors but created a run-time error and I have to abort the program. (
You should always give the *exact* error message.
Note that in versions of VC++ since 2003 when you define
a char string in that way it is placed in a «read-only»
area of memory and so the string *cannot* be changed later.
Any attempt to do so will cause a run-time error. So to
catch any such attempt to change the string at *compile*
time, you should declare it as a pointer to const char:
const char *stack=»″;
«String literals now have the type const char [] and are now
placed in a read-only section of memory. Changing that memory
will now cause an access violation.»
Of course, in this case each pointer holds the address of
a zero-length string so it would be impossible to copy a
longer string to that address without causing a memory
overwrite even if they weren’t in a read-only area.
Further, string literals are not STRINGS. They are arrays of const char.
In your case above you have a bunch of 2 character arrays. Even if you were allowed to store into them, you’d overfill them with things like gets_s(symbol, 20) as it’s only 2 char’s long.
This is C++ ditch the horrendous C stdio library, it’s lack of a string type, and your non-comprehension of memory allocation and write in C++ using the std::string class and iostream classes.
Thanks for the reply.
I understand what you are trying to explain but what if I REALLY want to store these random values only. as during the correct phase of time I am assigning them the value what I want to assign.
So isn’t there a way that will not consider assigning theses random value to a variable as an error.
This is the question I want answer for?
Thanks a lot for helping me.
But just clear me one more thing. The methods you are describing me are those which contains a fix size for the array. What if I don’t want this size boundation.
I mean is there a way to point to memory that will contain a sequence of chars plus I don’t need to declare the size also as it is not already known what will be the size plus I don’t want to assign any values in the starting as I want it to be entered when I will be requiring the need for it.
Also if I follow one of your methods and declare the arrays like this:
Then I meet a series of errors which makes the entire code to be modified. The errors are listed below:
Error 1 error C2106: ‘=’ : left operand must be l-value
Error 6 error C2106: ‘=’ : left operand must be l-value
Error 2 error C2105: ‘++’ needs l-value
Error 3 error C2105: ‘++’ needs l-value
Error 4 error C2105: ‘++’ needs l-value
Error 5 error C2105: ‘++’ needs l-value
Please guide me what I should do in this situation.
Any reply would be really appreciated. )
Also if I follow one of your methods and declare the arrays like this:
Then I meet a series of errors which makes the entire code to be modified. The errors are listed below:
Error 1 error C2106: ‘=’ : left operand must be l-value
Error 6 error C2106: ‘=’ : left operand must be l-value
Error 2 error C2105: ‘++’ needs l-value
Error 3 error C2105: ‘++’ needs l-value
Error 4 error C2105: ‘++’ needs l-value
Error 5 error C2105: ‘++’ needs l-value
You should probably change the code to something like:
Also, post needs to be initialized. I don’t understand this algorithm well enough to tell you how it needs to be initialized; it doesn’t make sense to me.
As a final comment, if you are going to program in C or C++, you need a basic understanding of pointers and arrays before you can move forward. It’s clear from your post that you are confused over these fundamental concepts.
This material is covered in every introductory C or C++ textbook. I suggest you re-read this material, or Google/Bing for «pointers arrays C» and a number of tutorials will pop up.
Thanks for taking the interest in the post.
But just tell me one thing—how to use a pointer to characters say «name» in which I want to take the entry of the name of the user from keyboard, but the condition is that the size of the string should be exactly the same as the length of name, not a single byte more and not a single byte less. How can I do it in Visual c++?
For a turbo complier I simply use the following code:
#include
int main()
<
char *name;
cout >name;
cout
#include
int main()
<
char *name;
cout
Both code example you posted are not ok. You use the variable «char* name», but you never initialized an amount of memmory that is allocated to this pointer variable. Even if you are not getting an error or warning with your «Turbo compiler» (btw. what «Turbo compiler»? Turbo C++, . ). If you want to handle with dynamic memory you need to use i.e. new or malloc to get a memory block.
From my unserstanding of your problem you should get a good C / C++ book or online tutorial. I guess you did not understand the ifference between a normal variable and pointers. Here a nice tutorial on pointers:
At all I’d recommend the complete C & C++ Programming tutorial for you:
Note: Posted code pieces may not have a good programming style and may not perfect. It is also possible that they do not work in all situations. Code pieces are only indended to explain something particualar.
Thanks to all of you.
You all guided me. I am very happy that you took interest in my problem and mentioned me.
I got what you all were trying explain me.
And learning from your reply I corrected the code and created the CORRECT INFIX TO POSTFIX CONVERTER.
Below is the code. Do have a look at it and please comment how is it. Also please guide me if you still see something misconceptual in my code. I would be very glad to see my silly mistakes. ). Thanks a lot to all of you. ). Learned a lot form you. )
Источник
Error c4700 uninitialized local variable
Hello people, this is my first time using this site so cut me some slack if I have trouble. I am in currently Foundations and Computer Programming II learning how to use C++ in more advance ways. I been given my first assignment and I’ve already came across an error that I don’t know how to fix. The error is «C4700: uninitialized local variable ‘n2’ used» and here is what I have.
void multiply( int , int );
Hey and welcome to this forum. Please make sure to read this post — http://www.cplusplus.com/forum/beginner/1/
And to always use code tags for all of your code — http://www.cplusplus.com/articles/jEywvCM9/
(You can edit your post now and use them to make it more readable)
This is not how the coma operator works. What you want is
Thank you for that tip Tarik, but now I have come across 2 more errors when I made that change. Both of them are error «LNK2019: unresolved external symbol.»
One error says ‘WinMain@16 referenced in function «int_cdel invoke_main(void)» (? invoke_main@@YAHXZ)’
The other one says ‘»void_decl multiply(int,int)» (?multiply@@YAXHH@Z) referenced in function_main’
I think this might be more of a file error, but I’m not sure. I should probably start another forum.
I should probably start another forum.
What does that even mean?
Your problem is simple, your function prototype and your function definition do not look idenetical, which they have to.
void multiply( int , int ); // takes 2 integers
void multiply( int & n1, int n2) // takes 2 integers, but the first one by reference
They have to look the same.
void multiply( int & n1, int n2); // change your function that is in multiply.h to this
Well there goes one of the errors. But the first one is still there.
‘WinMain@16 referenced in function «int_cdel invoke_main(void)» (? invoke_main@@YAHXZ)’
Источник
Добавлено 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Для начинающихОбучениеПрограммирование