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.
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 ran this code on Leetcode.com but it prints random numbers. It works on my local machine, however. Anybody know if variable shadowing is supposed to work across all compilers?
int carry = 0;
if (1) {
int carry = carry + 1;
cout << carry << endl;
}
The shadowing is defined by the C++ standard, and must work on all conforming compilers.
Your code prints garbage, because carry in carry + 1 reads the new variable (which isn't initialized at that point yet, causing UB), not the old one.
As #HolyBlackCat mentioned:
The shadowing is defined by the C++ standard, and must work on all
conforming compilers.
So because carry inside carry+1 takes the new carry, and that carry isn't initialized, anything can happened, as it's Undefined Behavior (UB).
Mind you, UB doesn't mean that the output is random, it just mean that anything can be printed out (so it may be consistent), and in some case you will get the correct answer.
Edit:
To the question "Why isn't it reading the older "carry" if the inner carry is undefined yet?".
It is designed this way within compiler, as #Nikita Demodov mentioned:
(For some reason) A variable is declared once it's identifier is reached. That's why
the carry after the = is the newly declared carry, rather that the
carry outside the if.
And as said in this documentation:
You can hide names with global scope by explicitly declaring the same
name in block scope. However, global-scope names can be accessed using
the scope-resolution operator (::).
In other word, whenever there is a local variable defined with same name as that of a global variable, the compiler will give precedence to the local variable.
By using the const qualifier a variable is supposed to be made read-only. As an example, an int marked const cannot be assigned to:
const int number = 5; //fine to initialize
number = 3; //error, number is const
At first glance it looks like this makes it impossible to modify the contents of number. Unfortunately, actually it can be done. As an example const_cast could be used (*const_cast<int*>(&number) = 3). This is undefined behavior, but this doesn't guarantee that number does not actually get modified. It could cause the program to crash, but it could also simply modify the value and continue.
Is it possible to make it actualy impossible to modify a variable?
A possible need for this might be security concerns. It might need to be of highest importance that some very valuable data must not be changed or that a piece of data being sent must not be modified.
No, this is not the concern of a programming language. Any "access" protection is only superficial and only exists at compile-time.
Memory of a computer can always be modified at runtime if you have the corresponding rights. Your OS might provide you with facilities to secure pages of memory though, e.g VirtualProtect() under Windows.
(Notice that an "attacker" could use the same facilities to restore the access if he has the privilege to do so)
Also I assume that there might be hardware solutions for this.
There is also the option of encrypting the data in question. Yet it appears to be a chicken-and-egg situation as the private key for the encryption and decryption has to be stored somewhere in memory as well (with a software-only solution).
While most of the answers in this thread are correct, but they are related to const, while the OP is asking for a way to have a constant value defined and used in the source code. My crystal ball says that OP is looking for symbolic constants (preprocessor #define statements).
#define NUMBER 3
//... some other code
std::cout<<NUMBER;
This way, the developer is able to parametrize values and maintain them easily, while there's virtually no (easy) way to alter it once the program is compiled and launched.
Just keep in mind that const variables are visible to debuggers, while symbolic constants are not, but they require no additional memory. Another criteria is the type checking, which is absent in case of symbolic constants, as well as for macros.
const is not intended to make a variable read-only.
The meaning of const x is basically:
Hey compiler, please prevent me from casually writing code in this scope which changes x.
That's very different from:
Hey compiler, please prevent any changes to x in this scope.
Even if you don't write any const_cast's yourself - the compiler will still not assume that const'ed entities won't change. Specifically, if you use the function
int foo(const int* x);
the compiler cannot assume that foo() doesn't change the memory pointed to by x.
You could use your value without a variable
Variables vary... so, naturally, a way to prevent that is using values which aren't stored in variables. You can achieve that by using...
an enumeration with a single value: enum : int { number = 1 }.
the preprocessor: #define NUMBER 1 <- Not recommended
a function: inline int get_number() { return 1; }
You could use implementation/platform-specific features
As #SebastianHoffman suggests, typical platforms allow marking some of a process' virtual memory space as read-only, so that attempts to change it result in an access violation signal to the process and the suspension of its execution. This is not a solution within the language itself, but it is often useful. Example: When you use string literals, e.g.:
const char* my_str = "Hello world";
const_cast<char*>(my_str)[0] = 'Y';
Your process will likely fail, with a message such as:
Segmentation fault (core dumped)
If you know the program at compile-time, you can place the data in read-only memory. Sure, someone could get around this, but security is about layers rather than absolutes. This makes it harder. C++ has no concept of this, so you'll have to inspect the resulting binary to see if it's happened (this could be scripted as a post-build check).
If you don't have the value at compile-time, your program depends on being able to change / set it at runtime, so you fundamentally cannot stop that from happening.
Of course, you can make it harder though things like const so the code is compiled assuming it won't change / programmers have a harder time accidentally changing it.
You may also find constexpr an interesting tool to explore here.
There is no way to specify what code does that does not adhere to the specification.
In your example number is truly constant. You correctly note that modifiying it after a const_cast would be undefined beahvior. And indeed it is impossible to modify it in a correct program.
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 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.