Note that I am using a Turbo C++ compiler because we are supposed to learn only Turbo C++ for our school syllabus. Which is why, the cout statement is evaluated from right to left in this case.
Program
#include <iostream.h>
#include <string.h>
void func(char *s, char t[]) {
strcpy(t, "Have fun");
s = "Be\0Cool";
cout << s[0] << ++s << s++ << --s << strupr(s+2) << ++s << s++ << s;
}
int main() {
char x[] = "Hello World!!!", y[] = "Hello World";
func(x, y);
cout << x << y;
return 0;
}
Output
CCOOLeeOOLBeBeHello World!!!Have fun
I feel the output should be:
CCooleeOOLBeBeHello World!!!Have fun
Because in the ++s part of the cout statement (second position), the pointer is at index 3 of the string s, so only 'Cool' should be printed. Instead 'COOL' is being printed. Why does this happen?
Tests with Visual Studio 2019
For comparison purpose, in Visual Studio 2019 (DEBUG), if we make required change to compile the code, then the program crash because we try to modify a constant string ("Be\0Cool").
If we do additional change to avoid the crash (by using a local array), the output is:
CCoOLeCoOLOLCoOLBeCoOLHello World!!!Have fun
If we split cout << s[]…; line to multiple calls to cout (one before each <<), then the output would be:
BeeeCOOLCOOLHello World!!!Have fun
Or if we add a line after each output, we get:
B
e
e
e
COOL
COOL
Hello World!!!
Have fun
Trying to understand the output of Turbo C++
If we then reverse each call to cout to start with the last (i.e. cout << s<< endl;) and end with first (cout << s[0] << endl), then we get:
Be
Be
OOL
e
e
COOL
C
Hello World!!!
Have fun
If we manually write that starting with the third last line and up and then the two last line in order without space, we get:
CCOOLeeOOLBeBeHello World!!!Have fun
Which is exactly what you got as an output.
Thus, it appears that Turbo C++ evaluate every expression from the right to the left.
Notes about required changes to compile (and run)
<iostream.h> is not available so I have to use <iostream> instead.
#define _CRT_SECURE_NO_WARNINGS must be added at top because some functions are not secure (and won't compile by default).
using namespace std; to avoid making more change to the code.
Add cast in s = (char *)"Be\0Cool"; so that line compile.
This lead to a crash because data is constant and we try to modify it.
Remove the cast and instead write char data[] = "Be\0Cool"; s = data;
The program run but the output is CCoOLeCoOLOLCoOLBeCoOLHello World!!!Have fun
In fact, this is undefined behavior. It just happen to be the actual output.
Undefined behavior
Some things are not defined by the standard and thus are not required to work a certain way. Well, as expected if read-only memory is not supported, it works like read-write memory.
For the order of evaluation, common possibilities are:
left to right
right to left
whatever is more optimal
Also since a variable is modified more than once, the value of s is not defined during the evaluation and afterward. The easy to remember rule is to avoid modifying the same variable more than once in a single expression.
About strupr
That function modify the string up to the terminating null character. In your case, it would convert to uppercase every letters from whatever value s has at the moment of the call.
Related
I initialized a variable i with a value 3, then put a statement (++i)++ in my code. But, in C, it is showing an error "lvalue required as increment operand". But, if I put this similar code in c++, it works and showing double increment with an output 5. However, one of my friends tried on his compiler using c and it gave an output 4.
//using c
#include <stdio.h>
int main()
{
int i=3;
(++i)++;
printf("%d",i);
return 0;
}
//using c++
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i=3;
(++i)++;
cout << i << endl;
return 0;
}
I am using GNU GCC compiler.
This is known to be undefined behavior. Syntactically this program is correct in C++, and the compiler produces some binary code... but the standard allows it to produce ANY code, even something that returns 100 or formats your disk. In real situations you may observe very strange abnormal scenarios, for example the compiler can drop the whole code after your (++i)++ statement, because the standard allows it to do whatever it wants right after the program enters into the status of UB. In your case that would mean that there would be no output at all (or the program would print "Hello World" instead of the integer value).
I believe that you are just conducting an experiment. The result is: both your compiler and your friend's are correct.
I was writing a simple program to test how the scope of variables works, but I'm obtaining unexpected results, so I was hoping you could give me an hand to understand them.
I compiled this code
#include<iostream>
using namespace std;
void myFunction1()
{
int e;
cout << e << endl;
e++;
cout << e << endl<<endl;
}
int main()
{
cout << "MAIN" << endl;
int a,b,c,d;
cout << "a= " << a << endl;
cout << "b= " << b << endl;
cout << "c= " << c << endl;
cout << "d= " << d << endl<<endl;
cout << "MY_FUNC" << endl;
myFunction1();
myFunction1();
myFunction1();
}
and obtained this output
MAIN
a= -1617852976
b= 32767
c= 0
d= 0
MY_FUNC
32675
32676
32676
32677
32677
32678
So, there are two things I really don't understand
1) In the main() function I'm creating 4 int variables (a,b,c,d) WITHOUT initializing them, so I expect them to assume a different value each time I run the code. Strange thing is, the first variable (a) is always different, while the others always assume the same values (b=32767, c=d=0)
2) The function output is even stranger to me.
Again, I'm creating a variable e without initializing it, so the first time it assumes a random value (in the example, e=32675).....then, I increase it by one, so that it prints 32675 and 32676, and that sounds right.
But how come the second time I call the function, e keeps the previous value (32676)? I thought e was created each time I call myFunction1() and deleted at the end of the function, so that e assumed a different random value each time (since I don't initialize it). Why is the value of e stored even if the variable goes out of scope?
Uninitialized primitive values are simply not defined. They can have any value.
It is an undefined behavior. That's why it doesn't make any sense to analyze the behavior of this program.
In the main() function I'm creating 4 int variables (a,b,c,d) WITHOUT initializing them, so I expect them to assume a different value each time I run the code
This assumption is flawed. They may have a different value each time you run the code, but they may not. Anything could happen. The point of UB is that you should drop all your assumptions.
But how come the second time I call the function, e keeps the previous value (32676)? I thought e was created each time I call myFunction1() and deleted at the end of the function, so that e assumed a different random value each time (since I don't initialize it)
It does. If you replace "random" for the more correct "arbitrary", then the results you're seeing fit that pattern just fine.
It's just pure luck, and comes down to the state you're leaving unclaimed memory in at each stage of your program's execution.
A good way to help you understand this is to explain in terms of memory allocation.
When you run a program, a certain amount of memory that is not used is assigned to your variable.
Computers are lazy, the best way to delete a data is to forget where it is stored. When you assign a chunk of memory to a variable, you are telling the computer to remember where that certain data belongs to.
If it so happens that it was used prior to you assigning the memory to the variable, it will simply read (let's say 4 bytes for a common machine) and get the data from that location.
Hope that this helps =)
This question already has answers here:
cout << order of call to functions it prints?
(3 answers)
Closed 9 years ago.
I have following simple program that initialize values for three variables and then gives output as expression.
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{
volatile int a = 10, b = 20, c = 30;
cout << a+b+c << " " << (c=c*2) << " "<< (b =b*2);
getch();
return 0;
}
Output I am getting for above code is
110 60 40
But a=10,b=20 and c=30 so a+b+c should be 10+20+30 = 60
This is because the arguments to the function are processed from right to left but are printed from left to right.
In C++, the order of evaluation of function arguments is undefined. That is, in the statement
std::cout << a+b+c << " " << (c=c*2) << " "<< (b =b*2);
you get different results depending on which subexpressions are evaluated first. A compiler can choose to evaluate the arguments to the output operators from left to right but it is also free to evaluate them in a different order, e.g., right to left, then do the appropriate functions calls.
The output from this code is undefined.
In C++, if assigning a variable, you are only allowed to use in the same statement for purposes of calculating the new value. Any other use has undefined effect.
(Note, you evaluate c for the purposes of printing (the 1st print clause), and for the purposes of calculating a new c (the c=c*2).
The later use is sanctioned, the former isn't.
Most compilers will calculate the first use of c as either the value before OR the value after the assignment, but in fact they arent even obliged to have it evaluate to anything related. And even if related, may not be a value it ever logically held, eg if the assignment were (c=2*c+5), you could just as easily find this mapped to c*=2, c+=5, and the first print clause might get the intermediate state, rather than the starting or end state.
The same problem exists for b. Compilers cant even be assume to be consistent in their handling of this, since what they do may reasonably depend on register allocation, which depends on local code.
I have a bunch of code roughly equivalent to this:
bool test(double e, short a, short b, short c) {
// Things being calculated here...
cout << "debug_3" << endl;
return (1 - abs(cos_th)) < (1 - cos(e));
}
int main() {
// something...
cout << "debug_0" << endl;
if(test(e,1,2,0)) {
cout << "debug_4" << endl;
// Bunch of useful operations...
}
// something...
}
Running the code generates the output:
debug_3
After which the program crashes (displaying "The program has stopped working..." in Windows). I have never encountered crashing at value return and I don't know what causes it or how I could fix it. Any thoughts on the issue?
EDIT: Some more info:
In my builds I also verify that the values of cos_th and e are valid.
People seem to point to the second something as the source of problems but my problem seems resolved (i.e. no crashes) when I get rid of the if-statement with a call to test()...
The only things we can fix without knowing what system is, is to change the type of a b and c to unsigned short since they are just array indexes, and make sure they are within array bounds. You might also need to make sure this is not zero since you divide by the result:
sqrt((Xca*Xca+Yca*Yca+Zca*Zca)*(Xba*Xba+Yba*Yba+Zba*Zba))
Use cerr instead of cout to make sure the output is flushed but you still don't see debug 4.
Put more output inside an else condition or after the if: maybe the function returns false?
If you can't locate the error precisely, use a debugger.
Crash at return usually means that your function overwrites stack (and thus the return address) and your program jumps to nowhere. You can verify this by stepping instruction by instruction at the disassembly level.
I came across this rather vague behavior when messing around with code , here's the example :
#include <iostream>
using namespace std;
int print(void);
int main(void)
{
cout << "The Lucky " << print() << endl; //This line
return 0;
}
int print(void)
{
cout << "No : ";
return 3;
}
In my code, the statement with comment //This lineis supposed to print out
The Lucky No : 3, but instead it was printed No : The Lucky 3. What causes this behavior? Does this have to do with C++ standard or its behavior vary from one compiler to another?
The order of evaluation of arguments to a function is unspecified. Your line looks like this to the compiler:
operator<<(operator<<(operator<<(cout, "The Lucky "), print()), endl);
The primary call in the statement is the one with endl as an argument. It is unspecified whether the second argument, endl, is evaluated first or the larger sub-expression:
operator<<(operator<<(cout, "The Lucky "), print())
And breaking that one down, it is unspecified whether the function print() is called first, or the sub-expression:
operator<<(cout, "The Lucky ")
So, to answer your question:
What causes this behavior? Does this has to do with C++ standard or its behavior vary from one compiler to another?
It could vary from compiler to compiler.
Let's call the operator << simply operator .
Now we can write
cout << "The Lucky"
as
operator(cout, "The Lucky")
The result of this operation is cout, and it is passed to next <<, so we can write
operator(operator(cout, "The Lucky"), print() )
It is a function invocation with two parameters, and the standard doesn't say anything about the order of their evaluation.
So with some compilers you really may get
The Lucky No : 3
In my compiler No: The Lucky 3 is the output.... it means that its behaviour varies from compiler to compiler.