This might be a beginner question and understanding how cout works is probably key here. If somebody could link to a good explanation, it would be great.
cout<<cout and cout<<&cout print hex values separated by 4 on a linux x86 machine.
cout << cout is equivalent to cout << cout.operator void *(). This is the idiom used before C++11 to determine if an iostream is in a failure state, and is implemented in std::ios_base; it usually returns the address of static_cast<std::ios_base *>(&cout).
cout << &cout prints out the address of cout.
Since std::ios_base is a virtual base class of cout, it may not necessarily be contiguous with cout. That is why it prints a different address.
cout << cout is using the built-in conversion to void* that exists for boolean test purposes. For some uninteresting reason your implementation uses an address that is 4 bytes into the std::cout object. In C++11 this conversion was removed, and this should not compile.
cout << &cout is printing the address of the std::cout object.
cout << &cout is passing cout the address of cout.
cout << cout is printing the value of implicitly casting cout to a void* pointer using its operator void*.
As already stated, cout << cout uses the void* conversion provided for bool testing (while (some_stream){ ... }, etc.)
It prints the value &cout + 4 because the conversion is done in the base implementation, and casts to its own type, this is from libstdc++:
operator void*() const
{ return this->fail() ? 0 : const_cast<basic_ios*>(this); }
cout<<&cout is passing the address of cout to the stream.
Related
test code:
#include <iostream>
using namespace std;
int main()
{
const char* b="str";
cout << b << endl;
cout << *b << endl;
cout << &b << endl;
cout << *(&b) << endl;
return 0;
}
result:
str
s
0x7ffdf39c27f0
str
I run my code on the web runoob online compiler
Why I get these results? I looked some questions about char*, but not enough for me to understand. Can someone explain that to me? Pictures are best.
I want to know more about it with books or blogs recommended.
By the way, usingchar b[] instead of const char*, I get the same results.
Thanks a lot for all of you.
I just want to know why a char pointer's value is not an address.
I think adress is like 0x7ffdf39c27f0. an memory adress.
But const char* b = "str". b is just str.
And I found that *b is the same as *("str").
So I want to know what happened in the memory? why a char pointer's value is not an address?
To understand what the code outputs, you need to understand that C++ output streams (objects with a type such as std::ostream) and therefore objects (such as std::cout) have a number of overloads of operator<<(). The overload that is called depends on the type of argument provided.
I'll explain your second example, but the explanation for the first example is almost identical.
const char* b="st\0r";
cout << b << endl;
cout << *b << endl;
cout << &b << endl;
cout << *(&b) << endl;
cout << b expands to cout.operator<<(b) where b has type const char *. That overload of the operator function ASSUMES the argument points to (the first character of) a nul terminated string, which is represented in memory as an array of char that ends with a char with value '\0' (zero). The operator function outputs each character it finds until it reaches a '\0' character. The first '\0' found is the one YOU explicitly inserted after the 't', so the output st is produced. The fact that your string has a second '\0' after the 'r' is irrelevant, since the operator function stops at the first one it finds.
cout << *b expands to a call of a different overload of operator<<() that accepts a single char, and outputs that char. *b is the value of the first character in the string represented by b. So the output s is produced.
In cout << &b, &b has type const char ** or (equivalently) char const **. There is no overload of an output stream's operator<<() that accepts a const char **, but there is an overload that accepts a const void *. Since any pointer (other than pointer-to-member or pointers to functions) can be implicitly converted to void *, that conversion is performed (by the compiler), so the overload matches, and is called. That particular overload of the operator<<() prints the address in memory.
The implicit conversion in the third case doesn't happen in the first two cases, since a call that doesn't require an implicit conversion is a better match than a call which does.
In the last statement *(&b) is equivalent to b. This is the case because & is the address-of operator in this code, and the * is the dereference operator (which is the inverse of the address-of operator). So the last statement produces the same output as cout << b.
cout << b << endl;
You are printing the string b
cout << *b << endl;
You are printing the pointer that points to the first character of b., so is the same as:
cout << b[0] << endl;
cout << &b << endl;
&b is the memory address of b, which means the address memory to store b in the computer.
cout << &b << endl;
So, you're printing the memory address of b here. The computer store b in the memory address 0x7ffdf39c27f0, so that's what you get.
cout << *(&b) << endl;
You are printing a pointer that points to the memory of b, so you print the value at the memory address of variable b which is the same as
cout << b << endl;
edit: A pointer contains an address that (usually, it could point at a function, for example) represents the location of an object, and to print a pointer (usually) prints the value of that memory address. Because char * is intimately linked with null-terminated strings, there is a special overload for pointers to characters to print the pointed-at string.
A pointer variable is still a variable and will have an address of its own, so &b results in a pointer to a pointer, a char ** in this case and because it is no longer a char *, cout << &b; prints the address of b, not the address pointed at by b or the string pointed at by b.
Why is the output of the below program what it is?
#include <iostream>
using namespace std;
int main(){
cout << "2+3 = " <<
cout << 2 + 3 << endl;
}
produces
2+3 = 15
instead of the expected
2+3 = 5
This question has already gone multiple close/reopen cycles.
Before voting to close, please consider this meta discussion about this issue.
Whether intentionally or by accident, you have << at the end of the first output line, where you probably meant ;. So you essentially have
cout << "2+3 = "; // this, of course, prints "2+3 = "
cout << cout; // this prints "1"
cout << 2 + 3; // this prints "5"
cout << endl; // this finishes the line
So the question boils down to this: why does cout << cout; print "1"?
This turns out to be, perhaps surprisingly, subtle. std::cout, via its base class std::basic_ios, provides a certain type conversion operator that is intended to be used in boolean context, as in
while (cout) { PrintSomething(cout); }
This is a pretty poor example, as it's difficult to get output to fail - but std::basic_ios is actually a base class for both input and output streams, and for input it makes much more sense:
int value;
while (cin >> value) { DoSomethingWith(value); }
(gets out of the loop at end of stream, or when stream characters do not form a valid integer).
Now, the exact definition of this conversion operator has changed between C++03 and C++11 versions of the standard. In older versions, it was operator void*() const; (typically implemented as return fail() ? NULL : this;), while in newer it's explicit operator bool() const; (typically implemented simply as return !fail();). Both declarations work fine in a boolean context, but behave differently when (mis)used outside of such context.
In particular, under C++03 rules, cout << cout would be interpreted as cout << cout.operator void*() and print some address. Under C++11 rules, cout << cout should not compile at all, as the operator is declared explicit and thus cannot participate in implicit conversions. That was in fact the primary motivation for the change - preventing nonsensical code from compiling. A compiler that conforms to either standard would not produce a program that prints "1".
Apparently, certain C++ implementations allow mixing and matching the compiler and the library in such a way that produces non-conforming outcome (quoting #StephanLechner: "I found a setting in xcode which produces 1, and another setting that yields an address: Language dialect c++98 combined with "Standard library libc++ (LLVM standard library with c++11 support)" yields 1, whereas c++98 combined with libstdc (gnu c++ standard library) yields an address;"). You can have a C++03-style compiler that doesn't understand explicit conversion operators (which are new in C++11) combined with a C++11-style library that defines the conversion as operator bool(). With such a mix, it becomes possible for cout << cout to be interpreted as cout << cout.operator bool(), which in turn is simply cout << true and prints "1".
As Igor says, you get this with a C++11 library, where std::basic_ios has the operator bool instead of the operator void*, but somehow isn't declared (or treated as) explicit. See here for the correct declaration.
For example, a conforming C++11 compiler will give the same result with
#include <iostream>
using namespace std;
int main() {
cout << "2+3 = " <<
static_cast<bool>(cout) << 2 + 3 << endl;
}
but in your case, the static_cast<bool> is being (wrongly) allowed as an implicit conversion.
Edit:
Since this isn't usual or expected behaviour, it might be useful to know your platform, compiler version, etc.
Edit 2: For reference, the code would usually be written either as
cout << "2+3 = "
<< 2 + 3 << endl;
or as
cout << "2+3 = ";
cout << 2 + 3 << endl;
and it's mixing the two styles together that exposed the bug.
The reason for the unexpected output is a typo. You probably meant
cout << "2+3 = "
<< 2 + 3 << endl;
If we ignore the strings that have the expected output, we are left with:
cout << cout;
Since C++11, this is ill-formed. std::cout is not implicitly convertible to anything that std::basic_ostream<char>::operator<< (or a non member overload) would accept. Therefore a standards conforming compiler must at least warn you for doing this. My compiler refused to compile your program.
std::cout would be convertible to bool, and the bool overload of the stream input operator would have the observed output of 1. However, that overload is explicit, so it shouldn't allow an implicit conversion. It appears that your compiler/standard library implementation doesn't strictly conform to the standard.
In a pre-C++11 standard, this is well formed. Back then std::cout had an implicit conversion operator to void* which has a stream input operator overload. The output for that would however be different. it would print the memory address of the std::cout object.
The posted code should not compile for any C++11 (or later conformant compiler), but it should compile without even a warning on pre C++11 implementations.
The difference is that C++11 made the convertion of a stream to a bool explicit:
C.2.15 Clause 27: Input/output library [diff.cpp03.input.output]
27.7.2.1.3, 27.7.3.4, 27.5.5.4
Change: Specify use of explicit in existing boolean conversion operators
Rationale: Clarify intentions, avoid workarounds.
Effect on original feature: Valid C++ 2003 code that relies on implicit boolean conversions will fail to
compile with this International Standard. Such conversions occur in the following conditions:
passing a value to a function that takes an argument of type bool;...
ostream operator << is defined with a bool parameter. As a conversion to bool existed (and was not explicit) is pre-C++11, cout << cout was translated to cout << true which yields 1.
And according to C.2.15, this should not longer compile starting with C++11.
You can easily debug your code this way. When you use cout your output is buffered so you can analyse it like this:
Imagine first occurence of cout represents the buffer and operator << represents appending to the end of the buffer. Result of operator << is output stream, in your case cout. You start from:
cout << "2+3 = " << cout << 2 + 3 << endl;
After applying the above stated rules you get a set of actions like this:
buffer.append("2+3 = ").append(cout).append(2 + 3).append(endl);
As I said before the result of buffer.append() is buffer. At the begining your buffer is empty and you have the following statement to process:
statement: buffer.append("2+3 = ").append(cout).append(2 + 3).append(endl);
buffer: empty
First you have buffer.append("2+3 = ") which puts the given string directly into the buffer and becomes buffer. Now your state looks like this:
statement: buffer.append(cout).append(2 + 3).append(endl);
buffer: 2+3 =
After that you continue to analyze your statement and you come across cout as argument to append to the end of buffer. The cout is treated as 1 so you will append 1 to the end of your buffer. Now you are in this state:
statement: buffer.append(2 + 3).append(endl);
buffer: 2+3 = 1
Next thing you have in buffer is 2 + 3 and since addition has higher precedence than output operator you will first add these two numbers and then you will put the result in buffer. After that you get:
statement: buffer.append(endl);
buffer: 2+3 = 15
Finally you add value of endl to the end of the buffer and you have:
statement:
buffer: 2+3 = 15\n
After this process the characters from the buffer are printed from the buffer to standard output one by one. So the result of your code is 2+3 = 15. If you look at this you get additional 1 from cout you tried to print. By removing << cout from your statement you will get the desired output.
#include <iostream>
using namespace std;
int main()
{
int *a = nullptr;
int b;
a = &b;
cout << noshowbase;
cin >> b;
cout << dec << a << '\t' << oct << a << '\t' << hex << a;
}
Consider this code.. It is designed to convert a variable's (here b) address (&b or a) which is a hex integer to dec and oct values using <iostream> stream manipulators.. But on running, the output is same for all of them(hex,dec,oct).. Neither, there is any compilation error. So can you please elaborate the reason for this?? Also the noshowbase does not seems to be having any effect on output.. 0x is output anyways before the address..
An address is not a hex integer. It's an address.
It just so happens that an address is implemented as an integer, referring to a memory location, and can be reinterpreted as an integer. This is rarely a useful thing to do (particularly if you are a fan of bug-free code), but it comes up now and again. You can use reinterpret_cast<uintptr_t>(a) to do that. (Note that converting to int will not, in general, work properly. Remember what I said about bug-free code.) When you print the resultant integer, it will print as a decimal, octal, or hexadecimal integer, depending on the currently-set base.
To address your topic, there is no such thing as a "hex integer". There are integers and they can be formatted as hex, but the formatting is not an intrinsic part of the integer.
Now, why are pointers always formatted as hex? The reason is that that's the way it is defined to work. I'd also call this convenient, but that might be because I'm familiar with the format and can read some information from it even better than from decimal output. The reason this doesn't change with formatters is that a pointer is not considered an integer. You will also find that pointer arithmetic doesn't behave like integer arithmetic, which is a case where the core language behaves like IOstreams.
So, how to get the format of your choice? Simple, convert the pointer to an integer first, then you can use the formatting of your choice. In order to do that, I would use size_t i = reinterpret_cast<size_t>(&b);. Depending on the compiler, I would also consider using uintptr_t instead of size_t, because that one is explicitly intended to hold information from a pointer.
You can cast the pointer to unsigned long first:
unsigned long p = (unsigned long) a;
cout << "dec=" << dec << p << endl;
cout << "oct=" << oct << p << endl;
cout << "hex=" << hex << p << endl;
This question already has answers here:
Why does std::cout output disappear completely after NULL is sent to it
(3 answers)
Closed 8 years ago.
I'm learning about pointers in C++. I wrote this simple program to show what I had a problem with:
#include <iostream>
using namespace std;
int main() {
cout << "test1";
char *ptr = 0;
cout << ptr;
cout << "test2";
}
When I run the program, it doesn't output "test2" at the end, instead only "test1". This should mean that it crashed when I tried to print out the value of ptr? I tried stepping through it in Eclipse debugger and it looks like every line gets executed but doesn't it throw an error or something?
char *ptr = 0;
cout << ptr;
There's an overload of the << operator that takes a char* operand, which it assumes is a pointer to a C-style string.
For pointer types other than char*, the << operator would print the value of the pointer (which is an address), but treating a null char* pointer as if it pointed to a C-style string causes undefined behavior. In any case, it's not going to print the pointer value.
To print the pointer value, you can convert it to void*:
cout << "test1\n";
char *ptr = 0;
cout << static_cast<void*>(ptr) << "\n";
cout << "test2" << "\n";;
Normally you can output a pointer to cout and it will print the address contained. However, when you output a char * it is interpreted as a C-style null-terminated string. In this case, it's a null pointer and does not point to a string.
Try casting it to a void * before outputting it.
I thought I understood pointers, but I think there's a nuance by how they're treated differently that I'm not quite following. When I pass an integer pointer or the address of an integer to showInt, it will print out the same memory address as it would outside the function. However. When I pass the following pointer to showChar;
char* value = "One";
showChar(value);
The address of the first element is different inside the function than it is outside the function. I understand that this is behaviour consistent with passing by value, and that a copy of the pointer is made within the function, however I was under the impression that a copy of a pointer still held the same address. Why is it different when dealing with pointers to char? If the char pointer just stores the address of the first element of the string literal, then why would the pointer in the function not point to the same memory location, but instead point to a new area in memory? That suggests to me that it isn't copying a char pointer, but creating a new char pointer and assigning it the value pointed to by the original pointer. If so, I don't understand why.
I understand that you can access the pointer address in the function by passing a pointer-to-pointer, or a reference-to-pointer instead, but why this is the case still confuses me.
Passing a pointer to char;
void showChar(char* name){
cout << name << endl;
cout << &name << endl;
}
Passing a pointer to int;
void showInt(int* num){
cout << num << endl;
cout << *num << endl;
}
The first line in showChar:
cout << name << endl;
will print the contents behind the pointer name, since the IO streams operators in C++ are overloaded to print char-pointers as text instead of the pointer as a number.
With the second line in this function
cout << &name << endl;
you don't print the pointer address name but instead the pointer (address) of the local variable name (which happens to be of a pointer type). That's taking the reference one time too much. What you want is change the behavior of how operator<<(ostream &, char*) works, namely printing the pointer address instead of printing a C-string.
You can do this by simply converting the pointer before passing it to cout, like this:
void showChar(char* name){
cout << (void*)name << endl;
}
Your showChar and showInt functions are printing different things.
In showChar, this:
cout << &name << endl;
prints the address of name, which is a local variable. In showInt, you don't print the value of # rather you print the value of num, which is an address, but not the address of a local variable.
In showChar, if you want to print value of name as an address, you'll need to convert it to some other pointer type such as void*:
cout << (void*)name << endl;
because the overload of operator<< for char* dereferences the char* pointer and prints the C-style string that it points to.
In more detail:
void showChar(char* name){
cout << name << endl; // prints the contents of the string that
// `name` points to
cout << &name << endl; // prints the address of the local variable `name`
}
void showInt(int* num){
cout << num << endl; // prints the value of the pointer `num`
cout << *num << endl; // prints the value of the `int` object that
// `num` points to
}