C++ program behaviour differs when compiled with Cygwin and MinGW - c++

I am fairly new to C++ and have been tinkering with some simple programs to teach myself the basics. I remember a little while ago installing MinGW on my desktop (I think for the C compiler). I decided to go for Cygwin for C++ and it seems to have been working a treat, up until I noticed that it seems to behave differently from the MinGW compiler for this program. I'm probably breaking some coding golden rule, but the reason for this is that Windows CMD uses the MinGW compiler, or I can open the Cygwin shell and use that instead. Variety!
For the program below, I am making notes on the ternary operator and switch statement. I initialize 'a' and 'b', ask for user input, and then use a function to check which is larger.
I then ask for user input again, to over-write the values in 'a' and 'b' to something else. When compiling from Windows CMD, this works fine and I can overwrite with new input, and the #define MAXIMUM and MINIMUM functions work fine on the new values. When I compile on Cygwin, however, after the first 'pause', the program launches past the two std::cin's and just runs MAXIMUM and MINIMUM on the old values of 'a' and 'b'.
Obviously I have tried just creating two new int variables, 'c' and 'd', and then there is no issue. The values are not immutable in any sense that I am aware of (although I don't know much, so I could be wrong).
I wasn't sure if this was something to do with the auto keyword, so I specified the type as int manually.
I also checked the version of both compilers with 'g++ -v' in Cygwin and at the CMD.
#include <iostream>
#include <cstdlib>
#define MAXIMUM(a,b) ((a > b) ? a : b)
#define MINIMUM(a,b) ((a < b) ? a : b)
int ternary_op(int a, int b)
{
char x = 'a';
char y = 'b';
auto result_var = 0;
result_var = a > b ? x : y; //Shorthand if statement with syntax (test_condition) ? (if_true) : (if_false)
return result_var;
}
int main()
{
auto a = 0;
auto b = 0;
auto larger = 0;
auto smaller = 0;
std::cout << "Enter an integer: " << "\n";
std::cin >> a;
std::cout << "Enter another integer: " << "\n";
std::cin >> b;
char greater_var = ternary_op(a,b); //Therefore if condition a > b is satisfied, greater_var is assigned x ('a')
std::cout << greater_var << std::endl;
switch(greater_var){
case 'a':
std::cout << "First integer " << a << " is larger than second, " << b << std::endl;
break;
case 'b':
std::cout << "Second integer " << b << " is larger than first integer, " << a << std::endl;
break;
}
std::cout << system("cmd /c pause") << std::endl;
std::cout << "We can also use defined functions to check equivalency and assign variables based upon the result." << "\n";
std::cout << "Enter an integer: " << std::endl;
std::cin >> a;
std::cout << "Enter another integer: " << std::endl;
std::cin >> b;
larger = MAXIMUM(a,b);
smaller = MINIMUM(a,b);
std::cout << "Larger and smaller numbers determined by defined function: " << larger << ", " << smaller << std::endl;
std::cout << system("cmd /c pause") << std::endl;
return 0;
}
Obviously if I make two new variables, 'c' and 'd', there is no issue. Changing the type to int myself did not change the way the program behaved using Cygwin. Unusually the MinGW version was 8.1.0, while Cygwin was 7.4.0. I'm not sure if this means that it is simply an older version of the same compiler.
Again, I'm very new to this so I'm just quite confused as to why they would behave so differently. I was also under the impression that different compilers were completely different beasts that simply read from the same standard hymn sheet, so to speak.
Just curious as to what is going on here!
Cheers!

Related

Printing addresses with 0x notation

Currently when I print an address of a variable,
cout << &a, its displayed as a simple hexadecimal number, let's say: 008FFBB8.
How can I print an address with the 0x notation? e.g. 0x6FFDF4.
I tried doing:
cout << hex << &a;
but it doesn't seem to work.
There are many different solutions, the first two that came into my mind are the following:
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
int main()
{
std::cout << std::hex
<< "showbase: " << std::showbase<< 42 << '\n'
<< "noshowbase: " << std::noshowbase << 42 << '\n';
//2nd solution
std::string a{"008FFBB8"};
std::cout << "Given: " << a << '\n';
a.erase(0,2);
a = "0x"+a;
std::cout << "Edited: "<< a <<'\n';
//3rd string to int so you can use standard arithmetics
int b = std::stoul(a, nullptr, 16);
std::cout << "Represented as int: " << b << '\n';
std::cin.get();
}
Edit:
This is how it is printed after compilation with GNU GCC(g++) compiler.
The reason visual studio isn't printing it as shown on the screenshot is because visual studio tend not to use GNU GCC but its Microsoft compiler MSVC.(There are other things MSVC isn't doing as you may expect btw.) But good news: you can make it! or here:)
It is just how hex is presented in your configuration with "MSVC"
I hope that answers your question, else leave a comment :)
A simple approach
cout << "0x" << &a;
That said, given that other systems do inlude 0x in &a, in order to make it portable, you should make cout << "0x" conditional based on predefined macro that detects the systems where 0x isn't included.
A portable solution is to insert into a string stream first, then check whether the prefix was added, and concatenate if it wasn't. this also prevents possibility of 0x and the address being separated by concurrent output.
I just wanted to know why Visual Studio is not displaying this notation by default,
Because the authors of their standard library chose to do so.
so I don't have to manually do it.
I'm not sure if there is a way to change their implementation. Before asking how, I recommend considering why you think that you have to do it.
Taking inspiration ;) from MSDN and trying it on VS 2019:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
ios state(nullptr);
int a;
state.copyfmt(cout); // save current formatting
cout << "In hex: 0x" // now load up a bunch of formatting modifiers
<< hex
<< uppercase
<< setw(8)
<< setfill('0')
<< &a // the actual value we wanted to print out
<< endl;
cout.copyfmt(state); // restore previous formatting
}
Output:
In hex: 0x00AFFB44
And as for why, well...you could raise an issue on MSVC and claim parity with all other compilers and platforms if you have the data. But given that they themselves manually slipped in the 0x I'm guessing they are already comfortable with the behavior.

C++ single quotes syntax

I am learning C++ and just started reading "Programming Principles and Practice" by Bjarne Stroustrup and he uses this code to illustrate a point:
#include "std_lib_facilities.h"
using namespace std;
int main() // C++ programs start by executing the function main
{
char c = 'x';
int i1 = c;
int i2 = 'x';
char c2 = i1;
cout << c << ' << i1 << ' << c2 << '\n';
return 0;
}
I am familiar in general with the difference between double and single quotes in the C++ world, but would someone kindly explain the construction and purpose of the section ' << i1 << '
Thanks
cout << c << ' << i1 << ' << c2 << '\n';
appears to be a typo in the book. I see it in Programming Principles and Practice Using C++ (Second Edition) Second printing. I do not see it listed in the errata.
According to the book, the intended output is
x 120 x
But what happens here is ' << i1 << ' attempts to compress the << i1 << to a multi-byte character and prints out an integer (most likely 540818464-> 0x203C3C20 -> ASCII values of ' ', '<', '<', ' ') because cout doesn't know wide characters. You'd need wcout for that. End result is output something like
x540818464x
and a warning or two from the compiler because while it's valid C++ code, it's almost certainly not what you want to be doing.
The line should most likely read
cout << c << ' ' << i1 << ' ' << c2 << '\n';
which will output the expected x 120 x
In other words, Linker3000, you are not crazy and not misunderstanding the example code.
Anyone know who I should contact to log errata or get a clarification on the off chance there is some top secret sneakiness going way over my head?
Before answering your question, here is a little background on what that is actually doing. Also note that there is a typo in the example, the string constant should have been double quoted:
cout << c << " << i1 << " << c2 << "\n";
In C++, operators can be overloaded so that they mean different things with different functions. In the case of cout, the << operator is overloaded as the "Insertion Operator". Think of it as taking the operand on the right, and inserting it (or sending it) into the operator on the left.
For example,
cout << "Hello World";
This takes the string "Hello World", and sends it to cout for processing.
So what beginners do not get is what something like this means:
cout << "Hello" << " World";
This is doing the same thing, but the operator precedence says to perform the injections from left to right. To make this work, the cout object returns itself as a function return value. Why is this important? Because the above statement is actually two separate operator evaluations:
(cout << "Hello") << " World";
This first injects "Hello" to cout, which outputs it, then continues to evaluate the next inject operator. Because cout returns itself, after the (cout << "Hello") is executed you have the following still to be evaluated:
cout << " World";
This expression injects " World" into the cout object, which then outputs " World", with the net effect being that you see "Hello World" just like the first time.
So in your example, what is it doing?
cout << c << " << i1 << " << c2 << "\n";
This is evaluated left to right as follows:
((((cout << c) << " << i1 << ") << c2) << "\n"); => Outputs value of c
((((cout ) << " << i1 << ") << c2) << "\n"); => Outputs string " << i1 << "
((( cout ) << c2) << "\n"); => Outputs value of c2
(( cout ) << "\n"); => Outputs newline character
( cout ); => No more output
Expression completes and returns the cout object as the expression value.
Assuming c='x' and c2='x', the final output from this expression is the following character string output on a single line:
x << i1 << x
For beginners, all those insertion operators << look a little strange. It is because you are dealing with objects. You could build the string up as a complete formatted object before injecting it into cout, and while that make the cout expression look simpler, we do not do that in C++ because it makes your code more complex and error prone. Note also, there is nothing special about the cout object. If you wanted to output to the standard error stream, you would use cerr instead. If you wanted to output to a file, your would instantiate a stream object that outputs to the desired file. That rest of the code in your example would be the same.
In C, the same thing would be done procedurally using a format string:
printf("%d << i1 << %d\n", i1, c2);
This is allowed in C++ too, because C++ is a superset of C. Many C++ programmers still use this output method, but that is because those programmers learned C first, and may not have fully embraced the object oriented nature of C++
Note that you may also have seen the << operator in the context of mathematical expressions like:
A = A << 8;
In this case, the << operator is the bitwise rotate operation. It has nothing to do with output to cout. It will rotate the bits in A to the left by eight bits.

Pointer to const variables in C++

I am just playing around to see where my current understanding of C++ behaviour ends. I wrote the following code, and got some very unexpected results.
#include <iostream>
#include <cstddef>
using namespace std;
int main()
{
const char c = 'A';
cout << c << endl;
size_t l = (size_t)(&c);
char* d = (char*)l;
*d = 'B';
cout << (size_t)d << " " << (size_t)&c << endl;
cout << *d << " " << c << endl;
}
The first line outputs 'A', as expected. On the second line, the two addresses are the same. However, the third line outputs "B A".
Obviously this is terrible code, but why didn't the value of c change (or why didn't it fail to compile?) In other words, if they both have the same address, why don't they have the same value?
My system is GCC 4.8.1 64-bit on MS Windows 7, x86, if it matters.

C++ snippet OK with MSVC but not with g++

I'm new to C++ and I try to adapt a program snippet which generates "weak compositions" or Multisets found here on stackoverflow but I run - to be quite frank - since hours into problems.
First of all, the program runs without any complaint under MSVC - but not on gcc.
The point is, that I have read many articles like this one here on stackoverflow, about the different behaviour of gcc and msvc and I have understood, that msvc is a bit more "liberal" in dealing with this situation and gcc is more "strict". I have also understood, that one should "not bind a non-const reference to a temporary (internal) variable."
But I am sorry, I can not fix it and get this program to work under gcc - again since hours.
And - if possible - a second question: I have to introduce a global variable
total, which is said to be "evil", although it works well. I need this value of total, however I could not find a solution with a non-global scope.
Thank you all very much for your assistance.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int total = 0;
string & ListMultisets(unsigned au4Boxes, unsigned au4Balls, string & strOut = string(), string strBuild = string()) {
unsigned au4;
if (au4Boxes > 1) for (au4 = 0; au4 <= au4Balls; au4++)
{
stringstream ss;
ss << strBuild << (strBuild.size() == 0 ? "" : ",") << au4Balls - au4;
ListMultisets(au4Boxes - 1, au4, strOut, ss.str());
}
else
{
stringstream ss;
ss << mycount << ".\t" << "(" << strBuild << (strBuild.size() == 0 ? "" : ",") << au4Balls << ")\n";
strOut += ss.str();
total++;
}
return strOut;
}
int main() {
cout << endl << ListMultisets(5,3) << endl;
cout << "Total: " << total << " weak compositions." << endl;
return 0;
}
C++ demands that a reference parameter to an unnamed temporary (like string()) must either be a const reference or an r-value reference.
Either of those reference types will protect you from modifying a variable that you don't realize is going to be destroyed within the current expression.
Depending on your needs, it could would to make it a value parameter:
string ListMultisets( ... string strOut = string() ... ) {
or it could would to make it a function-local variable:
string ListMultisets(...) {
string strOut;
In your example program, either change would work.
Remove the default value for the strOut parameter.
Create a string in main and pass it to the function.
Change the return type of the function to be int.
Make total a local variable ListMultisets(). Return total rather than strOut (you are returning the string value strOut as a reference parameter.)
The signature of the new ListMultisets will look like:
int ListMultisets(unsigned au4Boxes, unsigned au4Balls, string & strOut)
I'll let you figure out the implementation. It will either be easy or educational.
Your new main function will look like:
int main() {
string result;
int total = ListMultisets(5,3, result);
cout << endl << result << endl;
cout << "Total: " << total << " weak compositions." << endl;
return 0;
}

C++ Array passed by reference, but how to understand this?

The arrays are passed by reference. Any changes made to the array within the function changeArray will be observed in the calling scope (main function here).
However the codes below print 0 1 in the 1st cout, and print 2 in the 2nd "cout". What I don't understand is that why the first cout prints the original value of array[0]=1 instead of the changed value of array[0]=2?
Thanks a lot.
#include <iostream>
using namespace std;
int changeArray(int array[]) {
array[0]=2*array[0];
return 0;
}
int main() {
int array[]={1,2,3,4};
cout << changeArray(array) << " " << array[0] << endl;
cout << array[0] << endl;
return 0;
}
To make sure that the compiler doesn't reorder the execution:
cout << array[0] << endl;
changeArray(array);
cout << array[0] << endl;
This prints 1 and then 2.
The C++ compiler is allowed to optimize the code by reordering the execution of code within a single expression (e.g. cout << changeArray(array) << " " << array[0] << endl). To avoid that, and to make sure changeArray gets called first, you need to split your expression to separate statements, e.g. by using the semicolon (;). Everything before the semicolon gets executed before anything after the semicolon can start.