I had declared a Boolean variable bool abc; in a class and thought that it would be false by default. An if condition in my program, if (abc), turned out to be true, so I output the value of abc, and saw that it contained the value 55. Is this normal?
Do we always have to assign 'bool abc=false' to be sure that it is false?
Talking about primitive built-in data types (bool, char, wchar_t, short, int, long, float, double, long double), according to C++ standard, only global variables get a default value of zero if they are not explicitly initialized.
For local variables it's not required for the complier to clean up the content of the memory they are assigned to. A local variable -- if not explicitly initialized -- will contain an arbitrary value.
Yes, you should always initialize your variables. Until you intimately learn the times when it is and isn't necessary to do so explicitly, you should do it all the time, no matter what. And by then...well...why stop a good habit?
To initialize a bool to false it's sufficient to default construct it:
struct X
{
bool b;
X() : b() {}
};
Only global variables are assigned 0 (false) by default. Any local variables are given a non-zero garbage value, which would evaluate to true in a boolean variable.
Yes. You need to either do bool x=false or bool x(false). Primitives that are not initialized may have any value.
See Wikipedia
Yes. Always initialize your variables before use. Even if the language guarantees that they will have specific values. If you can't force yourself, get a compiler that will complain, and then make yourself do that. :)
However, don't initialize values unless it really has a meaning for them to be initialized. For example, if you have a loop like this (I'm not saying this is good code, it's just an example):
int i = 0;
while ((i = getNum()) == 5)
{
}
Don't initialize i to zero like I did. It makes no sense, and while it shuts up the compiler, it introduces the possibility that you'll forget it and then your code will be messed up. If you can force yourself to initialize only at the right times -- no more, no less -- then you'll make debugging a heck of a lot easier, since your wrong code will look wrong even at just a glance.
So, in one line: Never initialize just to prevent the compiler from complaining, but always initialize before use.
Related
In programming languages like Java, C# or PHP we can't use uninitialized variables. This makes sense to me.
C++ dot com states that uninitialized variables have an undetermined value until they are assigned a value for the first time. But for integer case it's 0?
I've noticed we can use it without initializing and the compiler shows no error and the code is executed.
Example:
#include <iostream>
using namespace std;
int main()
{
int a;
char b;
a++; // This works... No error
cout<< a << endl; // Outputs 1
// This is false but also no error...
if(b == '0'){
cout << "equals" << endl;
}
return 0;
}
If I tried to replicate above code in other languages like C#, it gives me compilation error. I can't find anything in the official documentation.
I highly value your help.
C++ gives you the ability to shoot yourself in the foot.
Initialising an integral type variable to 0 is a machine instruction typically of the form
REG XOR REG
Its presence is less than satisfactory if you want to initialise it to something else. That's abhorrent to a language that prides itself on being the fastest. Your assertion that integers are initialised to zero is not correct.
The behaviour of using an uninitialised variable in C++ is undefined.
It isn't feasible or even possible to detect or prove that variable is used uninitialized in all cases. For example:
int a;
if (<complex condition>)
a = 0;
if (<another complex condition>)
a = 1;
++a;
Can there be case when both conditions are false? You wouldn't know, unless you do an extensive analysis of your program. Pointers to variables can be passed, multithreading might be involved, making analysis even harder.
So, the decision was made to trust the programmer and merely declare those UB.
Modern compilers can issue warnings in many cases of uninitialized variable usage, and you should always use maximum warning level.
Anything is possible when your code has undefined behavior.
Correct code does not contain undefined behavior. Using the value of an uninitialized variable is undefined behavior.
The concept of undefined behavior is not unique to C++, but in C++ it is more important than elsewhere because there are so many chances to write wrong code without getting a compiler error.
However, the compiler is your friend. Use it! For example with gcc -Wall -Werror should be your default to get the error message:
<source>: In function 'int main()':
<source>:9:6: error: 'a' is used uninitialized [-Werror=uninitialized]
9 | a++; // This works... No error
| ~^~
<source>:13:5: error: 'b' is used uninitialized [-Werror=uninitialized]
13 | if(b == '0'){
| ^~
cc1plus: all warnings being treated as errors
Though, not all cases of undefined behavior can be caught by warnings (that can be treated as errors).
C++ dot com states that uninitialized variables have an undetermined value until they are assigned a value for the first time. But for integer case it's 0?
The correct term is indeterminate. As you can see in the above compiler output, there is no difference for your int a;. When anything can happen then undefined behavior can look like correct behavior, nevertheless it must be fixed.
TL;DR: You cannot use the value of an uninitialized variable. Code that compiles without errors is not necessarily correct.
There is no way to "mark" a variable as being uninitialized unless you store an extra bit of information somewhere, or reserve a value in the range of values that the data type covers. Plus every reference to the variable would have to test for uninitializedness.
All of this is completely unacceptable.
Also note that automatic variables are not implicitly initialized to some value (say 0) because this has a cost at run-time, even if the variable is not used.
As others have stated it's not always feasible for the compiler to detect if the variable is uninitialized and C and C++ prefer performance in those cases.
However, there are some additional points:
There are dynamic checkers that will detect if any of your test-cases uses an uninitialized variable. That only works if you don't zero-initialize them "just in case".
In C++ you can mix statements and declarations, so instead of
int a,b,c;
...
c=2;
a=12*c;
b=...;
you can write:
...
int c=2;
int a=12*c;
int b=...;
and if you don't modify them further you can add const as well, and lambdas are also useful for this.
If you really need to represent a possibly uninitialized variable use std::optional<...>. It can avoid some of those 'possibly uninitialized' cases and can detect if you try to access it when uninitialized. But it has a cost.
I have code like the following in a C++ project:
struct Foo {
union {
double d = 1.0;
char c;
};
};
When I run this through Clang-Tidy, it warns me that constructor does not initialize the field c. However, when I compile the code, I do not see any warning about this union's initialization.
Does this code have a potential problem lurking? Or is the warning from Clang-Tidy a false positive that can be safely ignored?
Actually, in that code, you can't initialize both variables. Check the structs and unions initialization rules. The compiler will throw something along this line Error: only one non-static data member of a union may have a default member initializer. So not only you can ignore the Clang warning, you have to in this particular case. If it's a false positive or a bug of Clang, can't say, but it clearly shouldn't be complaining about this, because fixing this warning will prevent your code from compiling.
On a more general note about these warnings. An uninitialized variable per se, won't break your program, until you try to do something that depends on the value of the variable, then many things could happen, some bad, some unknown, and some that even work fine.
By explicitly initializing the variable, you make sure it's in a consistent and known state, one which upon its use won't likely cause your program to break (unless the value you passed it made it so). Ignore these warnings at your own risk, if you really know what you're doing, or if they just don't make sense (like this one).
I have started learning C++ and I think the language is great, but few things are baffling me while I am on my path learning it. In this example:
cout << setiosflags(ios::fixed) << setiosflags(ios::showpoint);
In this example why do we type the whole setiosflags(ios::...) when the program still does the same if I only type showpoint without setiosflags?
Second question I have is simple. If we have the following:
int x=0;
cin>>x;
Why do we define a value for int if we later change it to something different than 0?
why do we type the wholesetiosflags(ios::...)when the program still does the same if I only type showpoint without setiosflags?
We don't, unless we want the program to be more verbose than necessary. As you say, streaming setioflags with a single flag is equivalent to streaming the flag itself. You might use setioflags if you have a pre-computed set of flags you want to set.
Why do we define a value for int if we later change it to something different than 0?
Again, we don't, unless we like unnecessary verbiage. But it's a good habit to initialise variables, to avoid undefined behaviour if you later change the code to assume it has been initialised.
Its optional and flexibility language provide, so either you can set manipulators using setiosflgas or as showing below:
float y= 1.45;
std::cout << std::fixed<<std::showpoint<<y;
Why insisting to initialize variables is because before C++11 these uninitialized variables can hold garbage value until you set value for them. And it may create unwanted issues and bugs. So better practice always initialize variables when you define it.
Since C++11 all fundamental data types are initialized to zero if you use explicit constructor as follows:
int i2 = int(); // initialized with zero
int i3{}; // initialized with zero (since C + + 11)
The stream manipulator std::setiosflags(ios_base::fmtflags mask)- is a function that sets the format flags specified by parameter mask. It can be used for multiple flags simultaneously, by using binary AND : &. It probably exists to provide full/complete functionality of the class that belongs to. Now regarding your question:
If you can access a flag(member) directly, why bother using a function(setter)?
I can't think of any reason why you shouldn't. However have in mind that manipulators are global functions and these constants, ios_base::fmtflags, are member constants. For more information on manipulators check this.
Regarding the second question: you initialize a variable when you define it to avoid undefined behaviour in case you use it, by mistake, before assigning it any value. Local variables need initialization, global variables are initialized by default.
When do I need to initialize variables in c++? Some people assert that its important but maybe this is more an issue in c-language?
I am refferering to primitives i.e. char, int, long, double
Let say I have the following code-snippet
int len;
double sum, mean;
char ch;
while (true) {
// here I use these primitives where they are initialized.
}
So - should I initialized these primitives as a good programming pratice here?
In c++ compiler usualy do not initialize local (automatic) variables. These variables are created on the stack and they are filled with random values. Usualy you do not need to inicialize variables but read carefuly what the compiler says. Try:
int main() {
int x;
x=x+1;
}
and compile it with -Wall switch (I'm using gcc). When the message
x.cpp: In function ‘int main()’:
x.cpp:3:6: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
x=x+1;
is written, then it would be better to initialize such variable.
The problem is, of course, the use of unitialised variables as in
int x;
int y=1+x; // oops what is y?
AFAIK, the language standard allows the compiler to initialise x to 0, but also to leave it unitialised. In any case, most optimisations (-O) will omit an initialisation in the above situation.
If you use full warning compiler flags (e.g. -Wall -Wextra -pedantic) the compiler will almost certainly spot the usage of unitialised variables (it will also warn about usage of unitialised variables in library header files, such as boost headers -- the boost developers appear to not use such useful diagnostics).
In general, whether or not to initialise all variables is a matter of style. I would provide an explicit initialisation whenever there is a sensible initial value for a variable and/or if there is the danger of it being used unitialised. Different from C, the possibility of unitialised variables is quite rare in C++, in particular when passing by return value (including move semantics).
You should initalize all variables to prevent: "trash in input - trash in output".
When do I need to initialize variables in c++?
You should initialize local variables with a sensible value when you define them. If you cannot give a variable a sensible value yet, then you should probably define it later.
The goal here is to minimize the amount of state in your functions in order to make them easier to understand. When all variables are defined at the beginning of the function, you don't know what they are used for. When they are defined at the point they are needed, it's clear that they are not used before that point. This also helps to limit the scope in which variables are declared (e.g. inside the loop instead of before it, thus less state outside the loop) and it allows you to define more variables as const (thus not adding state).
I am new to C++ programming. I am analyzing a code and I found the following:
typedef unsigned short UINT16;
typedef unsigned long UINT32;
typedef UNIT16 FLAG;
//within a structure,
struct x
{
const FLAG& flag; //what this means??
};
When I change the FLAG datatype to UNIT32, then FLAG& is returning some other value i guess. If i use FLAG instead of FLAG&, then it is behaving properly.
Please help me to understand the above.
Thanks in advance.
CONST is not part of C++, I would guess it is a macro of some kind.
FLAG & flag;
would create a reference to a flag object. Exactly what the code means/does is impossible to say without further information.
flag is a const member, so that it can only be initialized, not assigned to, unless there's a cast involved. What results you get depend on what you initialize it with, which you do not show.
flag is a reference (the &), so it doesn't keep its own value, but rather holds a value from somewhere else. A reference is simply a different name for another variable (or possibly a value, if it's a const ref). If you initialize it with a variable called i, for example, then it's another name for i. If the value of i changes, the value of flag changes. The const means that nothing in x can modify it directly, not that the value can't possibly be modified. Again, given no information about the initialization you're doing, it's impossible to explain what's going on.
You did mention that you got different results with FLAG and FLAG &, which indicates that you are initializing it with a variable, and the variable is then getting changed. Given more context, we could provide more detail.
Now, if you've provided the actual code, there is no difference between UINT16 and UINT32, since you've defined them both as unsigned short. There should be no difference in behavior. If there is, it means that you're providing not only insufficient code to know what's going on, but different code than you're actually getting your results from.