Why does explicitly calling operator<< on std::cout cause unexpected output? - c++

I was simply curious about what would happen if I called operator<< on std::cout explicitly because I learnt that a.operator() is exactly the same as a(). So I do it and it prints something weird:
#include <iostream>
using std::cout;
int main()
{
cout.operator<<("Hello World");
}
Output: 0x80486a0
Oddly, it outputs an address (the address may be different for you but it should still be an address). I'm thinking this is the address of the string so I try dereferencing it to get it to output the string:
*( cout.operator<<("Hello World") );
But I get a very long error
no match for operator* in '*std::cout.std::basic_ostream<...
I think this is pretty weird. Nothing of the std::cout definition would lead me to believe this would cause any different behavior; also given the fact that explicitly calling the operator function makes no difference (or should at least).
So why am I getting this output? Why am I receiving an address instead of the string itself when calling the operator explicitly? Is this even the address in memory or just garbage output? Any responses are appreciated.

The output operator for built-in strings, i.e., the on taking a char const* as argument, isn't a member of std::ostream. The operator taking a char const* is a non-member function would be called as
operator<< (std::cout, "Hello World");
There is, however, a member taking a void const* which formats the value of the pointer using hex notation. This member is the best match when passing any pointer explicitly to a member operator<< () of std::ostream.
Dereferencing the results of a the operator<<() doesn't work: The operators return a std::ostream& which doesn't have a unary operator*() overloaded. If you meant to dereference the argument, you'd call it like so:
std:cout.operator<< (*"Hello World");
However, this would just derference the char const* the string literal decays to, yielding an individual character H. The character output function isn't a member function, either, while the output operators for integers are, i.e., it would print character value of H. For a system using ASCII it would be 72.

I think the issue here is that the operator << that prints a C-style string to an output stream is actually a free function, not a member function of basic_ostream. However, basic_ostream does have an operator<< function that takes in a void* and prints out its address. As a result, if you explicitly try calling operator<< as a member function, you're calling the version that prints out an address of the C-style string, rather than the free function that prints out the characters a string.
You can see this by calling
operator<< (std::cout, "Hello, world!");
Which actually does print the string.
Hope this helps!

Related

If you have two consecutive cout statements, and end the first with << and no semi-colon, it still compiles on Mac. Why? [duplicate]

I am curious if std::cout has a return value, because when I do this:
cout << cout << "";
some hexa code is printed. What's the meaning of this printed value?
Because the operands of cout << cout are user-defined types, the expression is effectively a function call. The compiler must find the best operator<< that matches the operands, which in this case are both of type std::ostream.
There are many candidate operator overloads from which to choose, but I'll just describe the one that ends up getting selected, following the usual overload resolution process.
std::ostream has a conversion operator that allows conversion to void*. This is used to enable testing the state of the stream as a boolean condition (i.e., it allows if (cout) to work).
The right-hand operand expression cout is implicitly converted to void const* using this conversion operator, then the operator<< overload that takes an ostream& and a void const* is called to write this pointer value.
Note that the actual value resulting from the ostream to void* conversion is unspecified. The specification only mandates that if the stream is in a bad state, a null pointer is returned, otherwise a non-null pointer is returned.
The operator<< overloads for stream insertion do have a return value: they return the stream that was provided as an operand. This is what allows chaining of insertion operations (and for input streams, extraction operations using >>).
cout does not have a return value. cout is an object of type ostream. operator << has a return value, it returns a reference to cout.
See http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/ for reference.
The only signature that matches is:
ostream& operator<< (ostream& ( *pf )(ostream&));
so it returns the pointer to the operator<< member.
the one in James' answer. :)
I believe that would be the address of the ostream object that "" got printed to

Understanding behavior of cout.operator<<()

According to the top answer to this question, cout << expr is equivalent to cout.operator<<(expr).
According to responses to this question, the statement above is untrue.
According to my own testing, cout.operator<<() is the same as cout << when given an integer. When given a float, cout.operator<<() coerces it to an integer. When given a string literal, as in cout.operator<<("hello world"), it outputs what appears to be a memory address. And when given a variable holding a std::string, it gives a compiler error.
Could anyone give a beginner-to-intermediate-level explanation of what's going on?
It depends on expr.
The answers to both questions are speaking to that specific case, not a blanket guarantee.
In fact, some of the operator<<s are free functions, and some are member functions.
Consult your favourite C++ reference to find out which.
The equivalency of cout << expr and cout.operator<<(expr) depends on what expr is.
If it lands up being a "built in" type, that cout "knows" about, then yes, it is equivalent to cout.operator<<(expr) (a member function).
If it is a "user type" (and std::string counts here), then it is an overloaded non-member method with a signature akin to std::ostream& operator<<(std::ostream&, const std::string&); etc.
Why does cout.operator<<("hello world") print a memory address?
The best member method overload to the above (since it is being forced to use the member method, is ostream& operator<<(const void* value); which outputs the value of the pointer (not what is being pointed to).
By contrast, cout << "hello world" calls the non-member overload ostream& operator<<(ostream&, const char*) and this in-turn inserts each character into the output.

Strange thing with C++ memory management

Consider the output of this code:
char A = 'a';
char B[] = "b";
cout<<&A;
It outputs "ab" (the concatenation of A and B) and I wonder why. Please, explain me this.
Because &A is a char *. A string, represented by a char *, is required to have a '\0' terminating byte.
&A points to a single char, without a following '\0'. As such, attempting to print this text string results in undefined behavior.
You got an unexpected result because the operator << for objects of type char * is overloaded such a way that it outputs strings pointed to by pointers of the type char *.
It seems that your compiler placed the array B after the character A and in the memory they look like one string.
'a' 'b' '\0'
| |
A B
(It is unspecified in the C++ Standard whether A will precede B or B will precede A in the memory and whether there will be a gap due to padding bytes between the objects.)
If you want to output the address of the object A you should write for example
cout<< ( void * )&A;
or
cout<< ( const void * )&A;
or either ,like
cout<< static_cast<void *>( &A );
or like
cout<< static_cast<const void *>( &A );
It is unimportant whether the const qualifier will be specified for the pointer to a non-constant object because. It will be implicitly converted to the type const void * in the operator
basic_ostream<charT,traits>& operator<<(const void* p);
cout expects the char* parameter to point to a zero terminated string. But &A isn't zero terminated, so the precondition fails and this leads to undefined behavior.
Undefined behavior cannot really be explained, because the standard allows anything to happen. Displaying some more characters is one possible result. As is crashing. Or something else.
I wonder why
Because the stream insertion operator requires that any character pointer passed to it must point to a null terminated character string. The pointer passed to cout points to A which is not a null terminated character string. Since the pre-conditions (requirements) of the operation were not satisfied, the behaviour is undefined.
There are two relevant overloads for insertion operator (I've simplified away the template details, and the fact the one of these is a member overload, and the other is not):
ostream& operator<< (const void*);
ostream& operator<< (const char*);
All other pointers implicitly convert to void* and use the former overload and the pointer is outputed as a memory address. But the latter is favoured overload for character pointers, and the argument is required to be a null terminated string.
So, because a character pointer is interpreted as null terminated string, the naïve attempt to print the address of a character does not work. The solution: Cast the pointer to void* explicitly before passing to the stream.
The streams have been designed this way, in order to conveniently support null terminated strings, such as string literals which were considered to be (and are) streamed more typically than addresses. For example, it is convenient that std::cout << "Hello World!";. Prints "Hello World" instead of a memory address where the string literal is located.
This is a compiler-dependent behavior. Often, A nad B will be allocated one after the other on the stack. Taking the address of A will look like the zero-terminated string "ab". Don't do this! You rely on the stack frame layout the compiler is constructing.
because your char is not null terminated.
The behavior for this will UNDEFINED.
Your compiler has placed string comprising 'b' and '\0' immediately after character 'a' so once you've printed your A character as a string it found 'a', followed by 'b' followed by '\0' hence you have printed 'ab'

why is the address of a c++ function always True?

well why would,
#include <iostream>
using namespace std;
int afunction () {return 0;};
int anotherfunction () {return 0;};
int main ()
{
cout << &afunction << endl;
}
give this,
1
why is every functions address true?
and how then can a function pointer work if all functions share (so it seems) the same addresss?
The function address isn't "true". There is no overload for an ostream that accepts an arbitrary function pointer. But there is one for a boolean, and function pointers are implicitly convertable to bool. So the compiler converts afunction from whatever its value actually is to true or false. Since you can't have a function at address 0, the value printed is always true, which cout displays as 1.
This illustrates why implicit conversions are usually frowned upon. If the conversion to bool were explicit, you would have had a compile error instead of silently doing the wrong thing.
The function pointer type is not supported by std::ostream out of the box. Your pointers are converted to only possible compatible type - bool - and verything that is not zero is true thanks to backward compatibility to C.
There's no overload of operator<< for function pointers (except stream manipulators), but there is one for bool, so the function pointer is converted to that type before display.
The addresses aren't equal, but they're both non-null, and hence they both covert to true.
There is no overloaded function: operator<<(ostream&, int(*)()), so your function pointer is converted into the only type that works, bool. Then operator<<(ostream&, bool) is printing the converted value: 1.
You may be able to print the function address like so:
cout << (void*)&afunction << endl;
All addresses in C++ are non-zero, because zero is the NULL pointer and is a reserved value. Any non-zero value is considered true.
There cannot be an overload for function pointers for the iostream << operator, as there are an infinite number of possible function pointer types. So the function pointer gets a conversion applied, in this case to bool. Try:
cout << (void *) afunction << endl;
Which will give you the address in hex - for me the result was:
0x401344
Did you check anotherfunction() as well?
Anyway, C++ pointer addresses, like C pointer addresses, are usually virtual on most platforms and don't correspond directly to memory locations. Hence the value may be very small or unusual.
Also, they will always be true, as 0 is NULL, an invalid pointer, and anything that is over 0 is true

How does cout work when given an array? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does cout print char arrays differently from other arrays?
If I have this code:
char myArray[] = { 'a', 'b', 'c' };
cout << myArray;
It gives me this output:
abc
However, if I have this code:
int myArray[] = { 1, 2, 3 };
cout << myArray;
It gives me this output:
0x28ff30
Why does it not print out 123?
The reason that the first piece of code works is that the compiler is implicitly converting the array into a const char * character pointer, which it's then interpreting as a C-style string. Interestingly, this code is not safe because your array of characters is not explicitly null-terminated. Printing it will thus start reading and printing characters until you coincidentally find a null byte, which results in undefined behavior.
In the second case, the compiler is taking the int array and implicitly converting it into an int * pointer to the first element, then from there to a const void * pointer to the first element. Printing a const void * pointer with cout just prints its address, hence the output you're getting.
Hope this helps!
There is an operator << that knows about basic_ostream instances (such as cout) on the left-hand-side and const char*s on the right.
There is no such operator defined for const int* (or const int[]). Although you are perfectly at liberty to create one.
Just be sure to specify a sentinel at the end of your arrays to prevent running off the end of your buffer.
The reason you see the pointer value is because there is an basic_ostream::operator<<(const void*) which will print this.
std::cout is an instance of std::ostream, and there are several overloaded operators provided.
For example:
std::ostream& operator << (std::ostream&, char*);
When you type std::cout << somevar; compiler looks up best matching overload. First for exact type of the variable, then for anything it can be implicitly converted to (not to mention member functions/free functions/template functions, etc).
Here is a random article on C++ Overload Resolution
When you use myArray in the context cout << myArray;, it decays to a pointer. The operator<< which takes a char* as its second argument outputs a string; the one which takes other types of pointer just outputs an address. Hence the observed behaviour.
Your char array is actually not null-terminated, so I guess what you're seeing in the first case is really just undefined behaviour which happens to do 'the right thing' in this instance.
You haven't passed it an array of ints; you've passed it a pointer to an int. When faced with a pointer, it prints out the address that it points to. It has no way of printing out an array because it doesn't know how many elements it has (if any).
The reason it worked when you used a pointer to a character is that it knows that all arrays of characters are terminated by a NUL (\0) character, so it doesn't matter that you haven't told it the number of characters in your array. Keep in mind that your array is not terminated by a NUL, so it's only by luck that you got abc and no extra garbage characters on the end.
Because it has no way of knowing that your array is an array, or what kind of data is in it. When you do cout << myArray, 'myArray' is treated as a pointer type, which may point to anything. So instead of trying to dereference the pointer (and potentially crashing the app if the pointer has not been initialized), the address that the pointer is pointing to gets printed.