#include<iostream>
using namespace std;
int main ()
{
int cin;
cin >> cin;
cout << "cin" << cin;
return 0;
}
I saw this question here: http://quiz.geeksforgeeks.org/c-misc-c-question-8/
The output given by them is: cin + junk.
But I am unable to understand how it comes?
Please explain.
The "trick" in this question is
cin >> cin;
We're so used to seeing cin >> x to read x from the console that even when int cin; is present there is a chance you won't recognise cin >> cin as a bit-shift operation.
As has been mentioned, this is UB, which means you can't really expect anything. But in the absence of nasal demons, here's what you can sort of expect from a modern compiler:
The app chooses a register and calls it "cin".
It either does not overwrite whatever value that register still has from its last use, or - for a debug build - stores some magic number (chosen by the compiler author) into that register.
It then either shifts the value in cin right by cin bits and throws the answer away (i.e. cin is not modified by this operation.) - or the compiler eliminates cin >> cin completely because nothing after that line of code is dependant on the subtle side-effects it may have (such as setting the processor's zero flag)
The app then writes the string "cin" followed by the value in the register to the console.
The app ends cleanly, returning the value 0 to its caller (probably the OS).
tl;dr; It prints a random number because cin >> cin is a bit-shift operation with no side-effects, not an instruction to read input from the console.
The output given by them is: cin + junk.
While that is possible, the correct answer is: "I don't know, because the behaviour is undefined."
Let's go over the program line by line:
int cin;
A variable is default initialized. In this case, default initialization means that the value is indeterminate.
cin >> cin;
The bits of variable cin are shifted right for cin places. However, using an indeterminate value has undefined behaviour.
Rest of the program doesn't matter since behaviour is undefined.
In case you were wondering, std::cin is not involved because even though it is injected into the global namespace due to using namespace std, the local variable int cin shadows it.
Once cin is declared as integer, it can no longer be used for reading in operation.
Again it depends on scope of the cin variable. once the scope is over again cin functions as normal for reading in ops.
even same for cout also.
Related
I came across a code example learncpp.com where they zero-initialized a variable, then defined it with std::cin:
#include <iostream> // for std::cout and std::cin
int main()
{
std::cout << "Enter a number: "; // ask user for a number
int x{ }; // define variable x to hold user input (and zero-initialize it)
std::cin >> x; // get number from keyboard and store it in variable x
std::cout << "You entered " << x << '\n';
return 0;
}
Is there any reason that on line 7 you wouldn't just not initialize x? It seems zero-initializing the variable is a waste of time because it's assigned a new value on the next line.
Is there any reason that on line 7 you wouldn't just not initialize x?
In general, it is advised that local/block scope built in types should always be initialized. This is to prevent potential uses of uninitialized built in types which have indeterminate value and will lead to undefined behavior.
In your particular example though since in the immediate next line we have std::cin >> x; so it is safe to omit the zero initialization in the previous line.
Note also that in your example if reading input failed for some reason then prior to C++11, x still has indeterminate value but from C++11(&onwards) x will no longer has indeterminate value according to the below quoted statement.
From basic_istream's documentation:
If extraction fails (e.g. if a letter was entered where a digit is expected), zero is written to value and failbit is set. For signed integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() or std::numeric_limits<T>::min() (respectively) is written and failbit flag is set. For unsigned integers, if extraction results in the value too large or too small to fit in value, std::numeric_limits<T>::max() is written and failbit flag is set.
It seems zero-initializing the variable is a waste of time because it's redefined on the next line.
As i said, in your example and assuming you're using C++11(& higher), you can safely leave off the zero-initialization.
then defined it with std::cin
No the use of std::cin does not "define" it(x). Definition happened only once when you wrote:
int x{ }; //this is a definition
Even if you leave the zero initialization, then also it will be a definition:
int x; //this is also a definition but x is uninitialized here
The problem you're encountering is, that in order to use the >> operator of std::cin, you have to have your variable declared beforehand, which is, well, undesirable. It also leads to your question of whether or not to initialize the variable.
Instead, you could do something like this:
#include <iostream>
#include <iterator>
int main()
{
std::cout << "Enter a number: ";
auto const i = *std::istream_iterator<int>(std::cin);
std::cout << "You entered " << x << '\n';
}
... although that's also problematic, since you're at the end-of-file, then the behavior is undefined.
Now, you might be asking "why is this guys talking to me about alternatives to the common way of doing things, then telling me that the alternative isn't good enough either?"
The point of my doing this is to introduce you to an uncomfortable fact of "C++ life", which is: We are often stuck with design decisions of the standard library which are not optimal. Sometimes, there's really no better alternative; and sometimes there is, but it wasn't adopted - and since C++ does not easily change designs of standard library classes, we may be stuck with some "warts" in the language. See also the discussion in the related question I've opened:
Why do C++ istreams only allow formatted-reading into an existing variable?
#include <iostream>
using namespace std;
int main() {
int cin;
cin >> cin;
cout << "cin is : " << cin;
}
In this code it gets different output in different complier and can't find proper solution.
There are two things you probably don't understand: scope and initialization.
In the code below the global variable v is hidden by local variable v declared in main. All operations in main are performed on main's v. The same is true for cin. The cin you declared in main is not the same cin declared in std namespace. So, cin >> cin; has a different meaning. You probably expected the same behaviour as std::cin >> cin;.
double v;
int main()
{
int v;
}
c++ allows uninitialized variables. When you write int cin; memory space is allocated for cin, but nothing is written in (the variable is not automatically initialized). Leaving a variable uninitialized may be on purpose or not. Your compiler may be set to warn on uninitialized variables and/or check at run time. If you compile in debug configuration the variables may be automatically set to zero, depending on compiler, but you should not rely on this as your final build will be in release.
The answer to your question "Garbage value, Error, Segmentation fault, Nothing is printed" is garbage value (is this an interview question?):
cin is a local integer variable and
cin >> cin is different from std::cin >> cin and different from cin >>= cin.
Your code invokes undefined behavior. (Look up that term, it's an important concept that makes C++ an unreliable programming language.)
In the line int cin, you define a variable and don't initialize it.
The undefined behavior happens as soon as you read from the uninitialized cin variable.
The next undefined behavior happens depending on the value of cin. The shift-right operator is an arithmetic operation. If its right-hand side is not between 0 and the bit size of the left operand, the behavior is undefined.
you cannot declare keywords name for variable-name. cin and cout are keywords in c++.Please use different name for variable-name which used in your c++ program.
I'm trying to understand why does the following code compile?
#include<iostream>
using namespace std;
int main ()
{
int cin;
cin >> cin;
cout << "cin" << cin;
return 0;
}
How is the compiler able to distinguish in the statement: "cin >> cin"?
If you run the program, you'll notice that it never waits for input.
It doesn't distinguish anything – you're right-shifting the int by its own value.
(And that value is indeterminate, so the program is undefined.)
If you increase the warning level of your compiler, you should see "Warning: statement has no effect" or something to that effect.
To add on to molbdnilo's answer:
When you are using the statement using namespace std;, you are telling the compiler that for all variables in the current scope, loop up the identifier in current scope, if not, look up in the parent scope, until the look up reaches global scope and still unable to find the identifier, then it will try to find it in the namespace you are using.
After you declared int cin, everything that is called cin in the main function will be the local int cin not the std::cin, so all of your codes are just left shifting cin and shifting "cin" by cin amount of bits.
I was trying to solve this exercise from www.spoj.com : FCTRL - Factorial
You don't really have to read it, just do it if you are curious :)
First I implemented it in C++ (here is my solution):
#include <iostream>
using namespace std;
int main() {
unsigned int num_of_inputs;
unsigned int fact_num;
unsigned int num_of_trailing_zeros;
std::ios_base::sync_with_stdio(false); // turn off synchronization with the C library’s stdio buffers (from https://stackoverflow.com/a/22225421/5218277)
cin >> num_of_inputs;
while (num_of_inputs--)
{
cin >> fact_num;
num_of_trailing_zeros = 0;
for (unsigned int fives = 5; fives <= fact_num; fives *= 5)
num_of_trailing_zeros += fact_num/fives;
cout << num_of_trailing_zeros << "\n";
}
return 0;
}
I uploaded it as the solution for g++ 5.1
The result was: Time 0.18 Mem 3.3M
But then I saw some comments which claimed that their time execution was less than 0.1. Since I couldn't think about faster algorithm I tried to implement the same code in C:
#include <stdio.h>
int main() {
unsigned int num_of_inputs;
unsigned int fact_num;
unsigned int num_of_trailing_zeros;
scanf("%d", &num_of_inputs);
while (num_of_inputs--)
{
scanf("%d", &fact_num);
num_of_trailing_zeros = 0;
for (unsigned int fives = 5; fives <= fact_num; fives *= 5)
num_of_trailing_zeros += fact_num/fives;
printf("%d", num_of_trailing_zeros);
printf("%s","\n");
}
return 0;
}
I uploaded it as the solution for gcc 5.1
This time the result was: Time 0.02 Mem 2.1M
Now the code is almost the same, I added std::ios_base::sync_with_stdio(false); to the C++ code as was suggested here to turn off the synchronization with the C library’s stdio buffers. I also split the printf("%d\n", num_of_trailing_zeros); to printf("%d", num_of_trailing_zeros); printf("%s","\n"); to compensate for double call of operator<< in cout << num_of_trailing_zeros << "\n";.
But I still saw x9 better performance and lower memory usage in C vs. C++ code.
Why is that?
EDIT
I fixed unsigned long to unsigned int in the C code. It should have been unsigned int and the results which are shown above are related to the new (unsigned int) version.
Both programs do exactly the same thing. They use the same exact algorithm, and given its low complexity, their performance is mostly bound to efficiency of the input and output handling.
scanning the input with scanf("%d", &fact_num); on one side and cin >> fact_num; on the other does not seem very costly either way. In fact it should be less costly in C++ since the type of conversion is known at compile time and the correct parser can be invoked directly by the C++ compiler. The same holds for the output. You even make a point of writing a separate call for printf("%s","\n");, but the C compiler is good enough to compile this as a call to putchar('\n');.
So looking at the complexity of both the I/O and computation, the C++ version should be faster than the C version.
Completely disabling the buffering of stdout slows the C implementation to something even slower than the C++ version. Another test by AlexLop with an fflush(stdout); after the last printf yields similar performance as the C++ version. It is not as slow as completely disabling buffering because output is written to the system in small chunks instead of one byte at a time.
This seems to point to a specific behavior in your C++ library: I suspect your system's implementation of cin and cout flushes the output to cout when input is requested from cin. Some C libraries do this as well, but usually only when reading/writing to and from the terminal. The benchmarking done by the www.spoj.com site probably redirects input and output to and from files.
AlexLop did another test: reading all the inputs at once in a vector and subsequently computing and writing all output helps understanding why the C++ version is so much slower. It increases performance to that of the C version, this proves my point and removes suspicion on the C++ formatting code.
Another test by Blastfurnace, storing all outputs in an std::ostringstream and flushing that in one blast at the end, does improve the C++ performance to that of the basic C version. QED.
Interlacing input from cin and output to cout seems to cause very inefficient I/O handling, defeating the stream buffering scheme. reducing performance by a factor of 10.
PS: your algorithm is incorrect for fact_num >= UINT_MAX / 5 because fives *= 5 will overflow and wrap around before it becomes > fact_num. You can correct this by making fives an unsigned long or an unsigned long long if one of these types is larger than unsigned int. Also use %u as the scanf format. You are lucky the guys at www.spoj.com are not too strict in their benchmarks.
EDIT: As later explained by vitaux, this behavior is indeed mandated by the C++ standard. cin is tied to cout by default. An input operation from cin for which the input buffer needs refilling will cause cout to flush pending output. In the OP's implementation, cin seems to flush cout systematically, which is a bit overkill and visibly inefficient.
Ilya Popov provided a simple solution for this: cin can be untied from cout by casting another magical spell in addition to std::ios_base::sync_with_stdio(false);:
cin.tie(nullptr);
Also note that such forced flush also occurs when using std::endl instead of '\n' to produce an end of line on cout. Changing the output line to the more C++ idiomatic and innocent looking cout << num_of_trailing_zeros << endl; would degrade performance the same way.
Another trick to make iostreams faster when you use both cin and cout is to call
cin.tie(nullptr);
By default, when you input anything from cin, it flushes cout. It can significantly harm performance if you do interleaved input and output. This is done for the command line interface uses, where you show some prompt and then wait for data:
std::string name;
cout << "Enter your name:";
cin >> name;
In this case you want to make sure the prompt is actually shown before you start waiting for input. With the line above you break that tie, cin and cout become independent.
Since C++11, one more way to achieve better performance with iostreams is to use std::getline together with std::stoi, like this:
std::string line;
for (int i = 0; i < n && std::getline(std::cin, line); ++i)
{
int x = std::stoi(line);
}
This way can come close to C-style in performance, or even surpass scanf. Using getchar and especially getchar_unlocked together with handwritten parsing still provides better performance.
PS. I have written a post comparing several ways to input numbers in C++, useful for online judges, but it is only in Russian, sorry. The code samples and the final table, however, should be understandable.
The problem is that, quoting cppreference:
any input from std::cin, output to std::cerr, or program termination forces a call to std::cout.flush()
This is easy to test: if you replace
cin >> fact_num;
with
scanf("%d", &fact_num);
and same for cin >> num_of_inputs but keep cout you'll get pretty much the same performance in your C++ version (or, rather IOStream version) as in C one:
The same happens if you keep cin but replace
cout << num_of_trailing_zeros << "\n";
with
printf("%d", num_of_trailing_zeros);
printf("%s","\n");
A simple solution is to untie cout and cin as mentioned by Ilya Popov:
cin.tie(nullptr);
Standard library implementations are allowed to omit the call to flush in certain cases, but not always. Here's a quote from C++14 27.7.2.1.3 (thanks to chqrlie):
Class basic_istream::sentry : First, if is.tie() is not a null pointer, the function calls is.tie()->flush() to synchronize the output sequence with any associated external C stream. Except that this call can be suppressed if the put area of is.tie() is empty. Further an implementation is allowed to defer the call to flush until a call of is.rdbuf()->underflow() occurs. If no such call occurs before the sentry object is destroyed, the call to flush may be eliminated entirely.
I'm trying to write a simple test program in VS 2013. It's telling me that scanf() is unsafe, and that I should use scanf_s() instead. Even worse, it's telling me that int x is uninitialized (and not just as a warning, as an error), even though it doesn't need to be initialized there. I'm wondering if it's possible to change settings so that VS2013 does not give me these error messages, or figure out what I am doing wrong.
#include <stdio.h>
int main(){
printf("How many pizzas did you make: ");
int x;
scanf("%d", x);
}
use cout instead of printf() and cin instead of scanf
example:
const int SIZE = 5;
char word[SIZE];
cout << "Enter a word: ";
cin >> setw(SIZE) >> word;
cout << "You entered " << word << endl;
don't forget to import the std library
using std;
you may be making mistake in the this line
scanf("%d", &x);
scanf is warned as unsafe because it may cause buffer overflow. And scanf needs address of x, so it should be &x.
There is one outright error and a probable bug in your example code:
scanf("%d", x);
The above needs a pointer, and you must always verify that all output parameters were matched.
To the second, Microsoft is behind the drive to force you to abandon the standard C library functions, going so far as to declaring their use an unsupportable risk, not that the safer functions in an optional part of the C standard cannot be used in an unsafe manner too.
Look in the compiler documentation, there is a flag to suppress this irritating behavior.
Anyway, you are writing in C++, so just about everyone here will say you should use iostreams and idiomatic C++, regardless of how you ask or why.