What does the + operator do in cout? - c++

In the following code I got confused and added a + where it should be <<
#include <iostream>
#include "Ship.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
char someLetter = aLetter(true);
cout <<"Still good"<<endl;
cout << "someLetter: " + someLetter << endl;
return 0;
}
Should be
cout << "someLetter: " << someLetter << endl;
The incorrect code outputted:
Hello world!
Still good
os::clear
What I don't understand is why the compiler didn't catch any errors and what does os::clear mean? Also why wasn't "someLetter: " at the start of the line?

Here, "someLetter: " is a string literal, i.e. a const char * pointer, usually pointing to a read-only area of memory where all the string literals are stored.
someLetter is a char, so "someLetter: " + someLetter performs pointer arithmetic and adds the value of someLetter to the address stored in the pointer. The end result is a pointer that points somewhere past the string literal you intended to print.
In your case, it seems the pointer ends up in the symbol table and pointing to the second character of the name of the ios::clear method. This is completely arbitrary though, the pointer might end up pointing to another (possibly inaccessible) location, depending on the value of someLetter and the content of the string literal storage area. In summary, this behavior is undefined, you cannot rely on it.

The + operator has nothing to do with cout.
As seen in this table, + has higher precedence than <<, so the offending line of code gets parsed as follows:
(cout << ("someLetter: " + someLetter)) << endl;
In other words, + is applied to a char pointer and a char. A char is an integral data type, so you are really performing pointer arithmetics, adding the integer value of the char on the right-hand side to the pointer on the left-hand side, producing a new char pointer.

The + is doing pointer arithmatic on "someLetter: ".

I think that the C string "someLetter: " is using the char someLetter as an index, and therefore pointing to some part of memory. Hence the behaviour.
In C++ if you do silly things you get strange behaviour. The language gives you plenty of rope to hang yourself with.

You have to remember that literal string are just pointers to some memory area. What "someLetter: " + someLetter does is adding a value to that pointer and then trying to print that.

Related

Are there any exceptions to const char*?

If cstring is a pointer, then why can it get a value directly? Secondly, Why wasn't the ‍‍‍*cstring's result equal to whole of string? Third, cstring is a non-constant pointer to a constant character, so why change its value and not change its address?
#include <cstdio>
#include <conio.h>
#include <iostream>
using namespace std;
int main()
{
const char* cstring = "string";
cout << cstring << endl << *cstring << endl << &cstring << endl;
cstring = "foo";
cout << cstring << endl << *cstring << endl << &cstring << endl;
_getch();
return 0;
}
If cstring is a pointer, then why can it get a value directly?
The operator << of cout for const char* is specialized to behave that way. It will treat the pointer as a NULL terminated string and will print it instead of the pointer value. For different types you get different behaviour. For char* you have the whole string printed.
Why wasn't the ‍‍‍*cstring's result equal to whole of string?
That is because the type of *cstring is char and again, operator << behaves correctly by just printing a single char. a const char* is essentially an array of char.An array is essentially a pointer to the first element of the array. If you use the * operator on a pointer you are accessing whatever the pointer points to. If it points to the first element, well, you get the first element.
Third, cstring is a non-constant pointer to a constant character, so why change its value and not change its address?
As you said, cstring is a non-constant pointer to constant data. You cannot change the place it points to (it is a constant pointer), but you can substitute the content of the pointed data with other stuff. You point to the same location but the content of that cell changes.
If cstring is a pointer, then why can it get a value directly?
Anyone can get the value pointed at by a pointer by dereferencing the pointer. That's what happens when you do std::cout << cstring. The proper overload gets chosen that prints the string represented by cstring assuming that is correctly formed, null-terminated C-style string.
Secondly, Why wasn't the ‍‍‍*cstring's result equal to whole of
string?
cstring is a const char*, so *cstring is a const char. Pass that to std::cout and it will call an overload that prints one char. The function that is called internally doesn't even know that this is just one char in a string.
Third, cstring is a non-constant pointer to a constant character, so
why change its value and not change its address?
You can't change the address of a variable. cstring is in a fixed place on the stack. You change the value of cstring, which is the address of the string that it's pointing to (it is now pointing to a different string, which has a different address, "string" of course stil has the same address).
What you probably wanted to try is this:
const char* cstring = "string";
std::cout << (void*)cstring << std::endl;
cstring = "foo";
std::cout << (void*)cstring << std::endl;
Now you can see the different addresses. One is the address of "string" and one is the address of "foo".

Weird output when using char double pointer

I get really weird output from the last cout statement, no idea what would be causing this:
char ex1_val = 'A';
char* ex1;
ex1 = &ex1_val;
cout << *ex1 << endl;
char** ex2;
ex2 = &ex1;
cout << *ex2 << endl;
Here's my output:
A
A����
ex2 is declared as char**, which means it's a pointer to a pointer to char.
When you print the contents of *ex2, you're dereferencing it once, so type of *ex2 is a pointer to char.
Effectively, the compiler assumes, that you want to print a C-style string, which is a NULL-terminated string. So it prints all bytes stored in memory, starting from A stored in ex1_val, followed by random values stored directly after that, until a NULL character is encoutered.
This is actually a very bad situation, as you never know when or if there's a NULL in memory. You might end up trying to access a memory area you're not allowed to use, which may result in crashing the application. This is an example of an undefined behaviour (UB).
To print out the actual contents of ex1_val via the ex2 pointer, you'd need to make it like this:
cout << **ex2 << endl;
where typeof(**ex2) is an actual char.
When you dereference ex2 (in *ex2) you get a pointer to a char (i.e. char*), and the operator<< overload to handle char* outputs it as a C-style zero-terminated string.
Since *ex2 doesn't point to a zero-terminated string, only a single character, you get undefined behavior.
You want to do cout << **ex2 << endl;
ex2, as you have declared it, as a pointer to a pointer to a character. Doing *ex2 only gets you the address of the pointer it is pointing to.

How does C++ interpret a cout with a '+' in it?

I've been moving back and forth with Java/C++ so I messed up with my console output and accidentally wrote lines like:
cout << "num" + numSamples << endl;
cout << "max" + maxSampleValue << endl;
Each of which gave me bits and pieces of other strings I had in my program. I realize my mistake now, but what was C++ interpreting those lines as so that they output different parts of different strings in my program?
There is a simple reason for this:
"num" and "max" are string literal. Their type is const char *.
Assuming numSamples is an integer, what you are doing is is pointer arithmetic.
You are basically printing a string that points to "num" + numSamples bytes.
If you did cout << "num" + 1 << endl this would print "um".
You probably figured it out, but the correct way to do this is: cout << "num" << numSamples << endl;
Also, you asked:
But what was C++ interpreting those lines as so that they output
different parts of different strings in my program?
As stated before, "num" is a string literal. Generally string literals sits in the same place in the binary program: .rodata. All other string literals sits in this region, so when you are advancing your pointer by a certain amount of bytes, you will likely points to some other string literals, thus printing (part of) them.
It is just pointer arithmetic. For instance,
cout << "num" + 1 << endl;
would print a string staring from ((address of)"num" + 1), i.e. "um".
If the value we add exceeds the length of the string, then we have undefined behavior.
Keep in mind that although iostreams overload << (and >>) to do I/O, these were originally defined as bit-shift operators. When the compiler's parsing the expression, it's basically seeing "operand, operator, operand", then checking whether the operands are of types to which that operator can be applied.
In this case, we have a string literal and (apparently) some sort of integer, and the compiler knows how to do math on those (after converting the string literal to a pointer).
From the compiler's viewpoint, however, this isn't a whole lot different from something like:
int a, b=1, c=2, d = 3;
a = b << c + d;
The difference is that with operands of type int, the meaning is fairly obvious: it's doing addition and bit-shifting. With iostreams, the meaning attached to << and >> change, but the syntax allowed for them in an expression is unchanged.
From the compiler's "viewpoint" the only question is whether the operands to + are of types for which + is allowed--in this case, you have pointer to char + integer, so that's allowed. The result is a pointer to char, and it has an overload of << that takes a left-hand operand of type ostream and a right-hand operator of type pointer to char, so the expression as a whole is fine (as far as it cares).
"num" type is char const [4]. If numSamples is integer, "num" + numSamples type is const char *. So you call operator << cor std::cout, that overloaded for const char * and prints string that starts from address addres("num") + numSamples in pointer arithmetic.
Try this:
cout << "num" + std::to_string(numSamples) << endl;
cout << "max" + std::to_string(maxSampleValue) << endl;
std::to_string() function you can find in <string>
if you look at operator_precedence, you will see that + gets evaluated before <<, which leaves this expression to be evaluated before being passed to the operator <<:
"num" + numSamples
Now "num" is going to be a static const char * and I'm assuming numSamples is an integral type. Since the left-hand side of the + is a pointer type and you are adding to it, that's pointer arithmetic. The cout now gets a pointer to a location in memory that is numSamples or maxSamplueValue more than the location of "num" or "max". Most likely all of your static strings were lined up in in the same region of memory which is why you saw them rather than random gibberish.

c++ pointer to specific element in char array returns all elements after the specified one

To recreate this little problem of mine use this code (Yes it's bruteforced and could be slimmed down):
char hello[] = "John";
char *ptr1 = &hello[0];
char *ptr2 = &hello[1];
char *ptr3 = &hello[2];
char *ptr4 = &hello[3];
std::cout << ptr1 << "$";
std::cout << ptr2 << "$";
std::cout << ptr3 << "$";
std::cout << ptr4 << "$";
as you may see after trying this code, it returns the following:
John$ohn$hn$n$
I have no idea why it takes all elements after the specified one.
Any help?
It's because you're printing the pointer, not the thing it points to. And char pointers in C programs often point to the start of a char[] which represents a '\0'-terminated string. That is why std::ostream (of which cout is an instance) has an overloaded << operator that outputs the entire string, up to the terminator.
To print just the character, dereference the pointers first:
std::cout << *ptr1 << "$";
You could also use references instead, which are treated largely as a substitute for the value itself:
char &ptr1 = hello[0];
ptr1 through ptr4 are also pointers to characters, therefore << will treat them as strings, and print them as such, giving you what you saw.
If you just want the characters at each location, lines of the form:
char ch1 = hello[0];
will work, as will changing the output to:
std::cout << *ptr1 << "$";
Your question seems to be based on some completely unfounded expectations. It looks like you expected your code to print a single character for each cout << ... line. But why did you expect it to do that? What you send to cout in your code is actually a char * pointer. Why did you expect cout to dereference that pointer for you and print the character? A normal thing to expect would be to see the pointer value in the output (the address), not the character value.
So, the question you should really be asking is not "why it prints several characters from my array?". The question you should really be asking is "why it prints any of my characters at all?". You never dereferenced your pointer. Yet, instead of pointer value the output contains a sequence of char objects that pointer was pointing to. I.e. apparently cout decided to dereference your pointer for you, even though you never explicitly asked it to. That is the question you should be asking: why did my pointer get dereferenced at all?
And the answer is that [const] char * pointers receive special treatment when sent to cout using << operator. There's a dedicated overloaded version of << operator introduced specifically for that purpose. That version of << operator will treat char * pointers as pointing to the beginning of a C-string. And that operator will output the entire C-string all the way to the zero terminator character. That is exactly what is happening in your experiment.
Note that if you use any other pointer type (like int *) for example, you will not see the pointed value (or values) in the output. You will see the implementation-dependent representation of the pointer itself.
if you want to print value at particular address then :
std::cout << *ptr1 << "$";
std::cout << *ptr2 << "$";
std::cout << *ptr3 << "$";
std::cout << *ptr4 << "$";
I am not entirely sure but if it cout receives a char pointer, it will print, everything until it reaches a blank in memory, (C style character string), and if you just want to print a character, you should print only the content of the variable, that means just pass the content not the memory location...

Why does cout << &r give different output than cout << (void*)&r?

This might be a stupid question, but I'm new to C++ so I'm still fooling around with the basics. Testing pointers, I bumped into something that didn't produce the output I expected.
When I ran the following:
char r ('m');
cout << r << endl;
cout << &r << endl;
cout << (void*)&r << endl;
I expected this:
m
0042FC0F
0042FC0F
..but I got this:
m
m╠╠╠╠ôNh│hⁿB
0042FC0F
I was thinking that perhaps since r is of type char, cout would interpret &r as a char* and [for some reason] output the pointer value - the bytes comprising the address of r - as a series of chars, but then why would the first one would be m, the content of the address pointed to, rather than the char representation of the first byte of the pointer address.. It was as if cout interprets &r as r but instead of just outputting 'm', it goes on to output more chars - interpreted from the byte values of the subsequent 11 memory addresses.. Why? And why 11?
I'm using MSVC++ (Visual Studio 2013) on 64 bit Win7.
Postscript: I got a lot of correct answers here (as expected, given the trivial nature of the question). Since I can only accept one, I made it the first one I saw. But thanks, everyone.
So to summarize and expand on the instinctive theories mentioned in my question:
Yes, cout does interpret &r as char*, but since char* is a 'special thing' in C++ that essentially means a null terminated string (rather than a pointer [to a single char]), cout will attempt to print out that string by outputting chars (interpreted from the byte contents of the memory address of r onwards) until it encounters '\0'. Which explains the 11 extra characters (it just coincidentally took 11 more bytes to hit that NUL).
And for completeness - the same code, but with int instead of char, performs as expected:
int s (3);
cout << s << endl;
cout << &s << endl;
cout << (void*)&s << endl;
Produces:
3
002AF940
002AF940
A char * is a special thing in C++, inherited from C. It is, in most circumstances, a C-style string. It is supposed to point to an array of chars, terminated with a 0 (a NUL character, '\0').
So it tries to print this, following on in to the memory after the 'm', looking for a terminating '\0'. This makes it print some random garbage. This is known as Undefined Behaviour.
There is an operator<< overload specifically for char* strings. This outputs the null-terminated string, not the address. Since the pointer you're passing this overload isn't a null-terminated string, you also get Undefined Behavior when operator<< runs past the end of the buffer.
Conversely, the void* overload will print the address.
Because operator<< is overloaded based on the data type.
If you give it a char, it assumes you want that character.
If you give it a void*, it assumes you want an address.
However, if you give it a char*, it takes that as a C-style string and attempts to output it as such. Since the original intent of C++ was "C with classes", handling of C-style strings was a necessity.
The reason you get all the rubbish at the end is simply because, despite your assertion to the compiler, it isn't actually a C-style string. Specifically, it is not guaranteed to have a string-terminating NUL character at the end so the output routines will just output whatever happens to be in memory after it.
This may work (if there's a NUL there), it may print gibberish (if there's a NUL nearby), or it may fall over spectacularly (if there's no NUL before it gets to memory it cannot read). It's not something you should rely on.
Because there's an overload of operator<< which takes a const char pointer as it's second argument and prints out a string. The overload that takes a void pointer prints only the address.
A char * is often - usually even - a pointer to a C-style null-terminated string (or a string literal) and is treated as such by ostreams. A void * by contrast unambiguously indicates a pointer value is required.
The output operator (operator<<()) is overloaded for char const* and void const*. When passing a char* the overload for char const* is a better match and chosen. This overload expects a pointer to the start of a null terminated string. You give it a pointer to an individual char, i.e., you get undefined behavior.
If you want to try with a well-defined example you can use
char s[] = { 'm', 0 };
std::cout << s[0] << '\n';
std::cout << &s[0] << '\n';
std::cout << static_cast<void*>(&s[0]) << '\n';