I'm just playing around a little bit with decltype and noticed the intellisense in VS 2012 is giving me a error. This is the first time I have encountered this and the code still compiled.
#include <iostream>
int func(int param)
{
std::cout << "IM BEING CALLED: " << param << std::endl;
return 0;
}
int main()
{
auto& y = func;
auto z = func;
decltype((func))& x = func;
decltype((func)) k = func; // function 'k' may not be initialized but compiles
func(9);
x(10);
y(11);
z(12);
k(13);
std::cout << std::endl;
std::cout << "Address of func: " << func << std::endl;
std::cout << "Address of x: " << x << std::endl;
std::cout << "Address of y: " << y << std::endl;
std::cout << "Address of z: " << z << std::endl;
std::cout << "Address of k: " << k << std::endl;
std::cin.get();
return 0;
}
This is not a major problem nor interesting for most people but I was just wondering if anyone knows the reason behind the error?
I was just wondering if anyone knows the reason behind the error
It's just a parsing bug. Nothing more, nothing less.
Related
I've tried to understand the semantics of c++ temporary objects lifetime extension. I've tried to simulate simple situation and was a bit surprised.
Below I'm providing my code.
#include <iostream>
struct C
{
C(const int new_a) { a = new_a; };
int a = 0;
};
C return_num()
{
C num(20);
std::cout << "From func(): num = " << num.a << ", by adress: " << &num.a << std::endl;
return num;
}
void pass_num(const C& num)
{
std::cout << "From func(): num = " << num.a << ", by adress: " << &num.a << std::endl;
}
int main()
{
std::cout << "\nLifetime extention:" << std::endl;
{
const C& ext_num = return_num();
std::cout << "From main(): num = " << ext_num.a << ", by adress: " << &ext_num.a << std::endl;
}
std::cout << "\nPassing by reference:" << std::endl;
{
C num(20);
std::cout << "From main(): num = " << num.a << ", by adress: " << &num.a << std::endl;
pass_num(num);
}
}
Here is the main question: return_num() works curiously from my point of view, cause I expected that address of the variable, which I'm trying to output in main, would be the same as internally in return_num(). Could you please explain me why it is not?
For example in pass_num() output address matches the external address which I got in main.
Here is example output:
Lifetime extention:
From func(): num = 20, by adress: 0x7fff44fc8b4c
From main(): num = 20, by adress: 0x7fff44fc8b70
Passing by reference:
From main(): num = 20, by adress: 0x7fff44fc8b6c
From func(): num = 20, by adress: 0x7fff44fc8b6c
Move constructors typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.) rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state.
Please see Move Constructor
I changed the below in your code and I hope it is working as expected. I changed int a to int* a
#include <iostream>
class C
{
public:
int *a;
C( int new_a)
{
a = new int();
*a = new_a;
};
C(const C& rhs) { std::cout << "Copy " << std::endl; this->a = rhs.a; }
C(C&& rhs):a(std::move(rhs.a))
{
std::cout << "Move!!" <<"Address resource a " << &(*a) << ", Address of
resource rhs.a" << &(*rhs.a) << std::endl; rhs.a = nullptr;
std::cout << "Value of a:: " << *a << std::endl;
}
};
C return_num()
{
C num(20);
std::cout << "From return_num(): num = " << *num.a << ", Address of resource a :
"<< &(*num.a)<< std::endl;
return (std::move(num));
}
void pass_num(const C& num)
{
std::cout << "From pass_num(): num = " << *num.a << ", by adress: " << &num.a <<
std::endl;
}
int main()
{
std::cout << "\nLifetime extention:" << std::endl;
{
const C& ext_num = return_num();
std::cout << "From main() 1 : num = " << *(ext_num.a) << ", by resource
adress: " << &(*ext_num.a) << std::endl;
}
std::cout << "\nPassing by reference:" << std::endl;
{
C num(20);
std::cout << "From main() 2 : num = " << *num.a << ", by adress: " << &num.a
<< std::endl;
pass_num(num);
}
return 0;
}
The above code produces below output:
Lifetime extention:
From return_num(): num = 20, Address of resource a : 0x7fffeca99280
Move!!Address resource a 0x7fffeca99280, Address of resource rhs.a0x7fffeca99280
Value of a:: 20
From main() 1 : num = 20, by resource adress: 0x7fffeca99280
Passing by reference:
From main() 2 : num = 20, by adress: 0x7ffff466f388
From pass_num(): num = 20, by adress: 0x7ffff466f388
I hope it helps!
Imagine this function:
int getNumber(){
int num = 10;
return num;
}
This function does not return num as an object, it returns a no-named copy of it (r-value, if you will) with the same value. Therefore, it has a different address.
The same thing happens with your return_num function.
I suspect that taking the address of a member is inhibiting the optimization because the compiler doesn't know how to deal with all the possible edge cases. Eliminating taking the address of the member makes the optimization work.
#include <iostream>
struct C
{
C(const int new_a) { a = new_a; };
int a = 0;
struct C* t = this;
};
C return_num()
{
C num(20);
std::cout << "From func(): num = " << num.a << ", by adress: " << num.t << std::endl;
return num;
}
void pass_num(const C& num)
{
std::cout << "From func(): num = " << num.a << ", by adress: " << num.t << std::endl;
}
int main()
{
std::cout << "\nLifetime extention:" << std::endl;
{
const C& ext_num = return_num();
std::cout << "From main(): num = " << ext_num.a << ", by adress: " << ext_num.t << std::endl;
}
std::cout << "\nPassing by reference:" << std::endl;
{
C num(20);
std::cout << "From main(): num = " << num.a << ", by adress: " << num.t << std::endl;
pass_num(num);
}
}
Lifetime extention:
From func(): num = 20, by adress: 0x7ffd61f48a50
From main(): num = 20, by adress: 0x7ffd61f48a50
Passing by reference:
From main(): num = 20, by adress: 0x7ffd61f48a90
From func(): num = 20, by adress: 0x7ffd61f48a90
I cant figure out why the output of this program is what it is. Maybe some one can help me out.
And why does the reference of double Pointer: 0062FB78?
Why does the reference of dereferenced double pointer = 0062FAA0?
Should'nt these be flipped?
0062FB78 is the address of x
I am guess 0062FAA0 is the address of the double Pointer?
#include <iostream>
void print(int x) {
std::cout << "value: " << (x) << "\n";
std::cout << "reference: " << (&x) << "\n";
//std::cout << (*x) << "\n";
}
void printPointer(int *x) {
std::cout << "value: " << x << "\n";
std::cout << "reference: " << &x << "\n";
std::cout << "dereference:" << *x << "\n";
}
void printDoublePointer(int **x) {
std::cout << "value: " << x << "\n";
std::cout << "reference: " << &x << "\n";
std::cout << "dereference:" << *x << "\n";
printPointer(*x);
}
void printTripplePointer(int ***x) {
std::cout << "value:" << x << "\n";
std::cout << "reference:" << &x << "\n";
std::cout << "dereference:" << *x << "\n";
printDoublePointer(*x);
}
void print(char* string) {
std::cout << "\n" << string << "\n";
}
int main()
{
int x = 19;
int *y; // y is a address space
y = &x; // &y now points to the address of x, *y now has the value of x
int **doublePointer = &y;
print(x);
printPointer(y);
printDoublePointer(doublePointer);
print("doublePointer");
std::cin >> x;
}
x
value: 19
reference: 0062FBB78
y
value: 0062FC7C
reference: 0062FBB78
defererence: 19
doublePointer
value: 0062FC58
reference of double Pointer: 0062FB78
dereference of doble Pointer: 0062FC7C
value of dereferenced double pointer: 0062FC7C
reference of dereferenced double pointer: 0062FAA0
dereference: 19
Before going over you problem, let's first agree that after calling y= &x, y is not a reference to x, but rather the address of x.
Now, let's examine the call to print
If you pay close attention, we pass the variable by-value, so this method will actually print the value 19, but the address will belong to a temp copy of x.
If we would have changed the prototype to the following one, the address of x printed here will be equal to the address of y printed in the method printPointer
void print(int & x) {
std::cout << __PRETTY_FUNCTION__ << "\n";
std::cout << "value: " << (x) << "\n";
std::cout << "reference: " << (&x) << "\n";
}
Regarding your other concern, these too occur because you pass the pointers by-value and not by-reference.
This simple program shows that everything works just fine:
int main()
{
int x = 19;
int *y = &x;
int **z = &y;
std::cout << x << "\t" << &x << std::endl;
std::cout << y << "\t" << &y << "\t" << *y << std::endl;
std::cout << z << "\t" << &z << "\t" << *z << std::endl;
}
I have this sample code below. I know little bit about RVO (return value optimization) and how copy constructor and assignment operator are skipped during the optimization and return of the value is placed directly on the memory on the left. So if shared pointer does the RVO how does the shared pointer know when to increase its counter? Because for some reason I thought shared pointer class would know when to increase counter based on the number copies or assignment it made.
#include <iostream>
#include <memory>
using namespace std;
class A{
public:
A(){}
A(const A& other){ std::cout << " Copy Constructor " << std::endl; }
A& operator=(const A&other){
std::cout << "Assingment operator " << std::endl;
return *this;
}
~A(){
std::cout << "~A" << std::endl;
}
};
std::shared_ptr<A> give_me_A(){
std::shared_ptr<A> sp(new A);
return sp;
}
void pass_shared_ptr_by_val(std::shared_ptr<A> sp){
std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl;
std::shared_ptr<A> sp1 = sp;
std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl;
std::cout << __func__ << ": count sp1 = " << sp1.use_count() << std::endl;
}
void pass_shared_ptr_by_ref(std::shared_ptr<A>& sp){
std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl;
std::shared_ptr<A> sp1 = sp;
std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl;
std::cout << __func__ << ": count sp1 = " << sp1.use_count() << std::endl;
}
int main(){
{
shared_ptr<A> sp3 = give_me_A();
std::cout << "sp3 count = " << sp3.use_count() << std::endl;
pass_shared_ptr_by_val(sp3);
pass_shared_ptr_by_ref(sp3);
}
return 0;
}
output:
sp3 count = 1
pass_shared_ptr_by_val: count sp = 2
pass_shared_ptr_by_val: count sp = 3
pass_shared_ptr_by_val: count sp1 = 3
pass_shared_ptr_by_ref: count sp = 1
pass_shared_ptr_by_ref: count sp = 2
pass_shared_ptr_by_ref: count sp1 = 2
~A
If there is no copy, nothing needs to be counted.
If RVO is in play no copy is made, so why would the ref-count need to be increased? There is no extra object to destroy and decrement the ref-count.
Say I want to check to see whether a subclass has implemented one of it's parent's virtual functions (never mind whether this smells of bad architecture... it's an exercise). If I wanted to see if two regular functions were identical, I could just check &f == &g.
// Plain old functions
void f() {}
void g() {}
...
std::cout << "&f " << &f << "\n"; // "1" OK, for some reason func ptrs are converted
std::cout << "&g " << &f << "\n"; // "1" to booleans when printed. I can dig it.
std::cout << "&f == &g " << (&f == &g) << "\n"; // "0" Good, &f and &g are unequal as expected.
But with virtual member functions, behavior is different.
// Base class with a virtual
struct A {
virtual void f() {}
};
// Subclass which implements f
struct B : public A {
void f() {}
};
// Subclass which doesn't implement f
struct C : public A {};
...
std::cout << "&A::f " << &A::f << "\n"; // "1"
std::cout << "&B::f " << &B::f << "\n"; // "1"
std::cout << "&C::f " << &C::f << "\n"; // "1" ... okay ... annoying, but alright.
std::cout << "&A::f == &B::f " << (&A::f == &B::f) << "\n"; // "1" DANGER - why does &A::f == &B::f if &f != &g?
std::cout << "&A::f == &C::f " << (&A::f == &C::f) << "\n"; // "1"
std::cout << "&B::f == &C::f " << (&B::f == &C::f) << "\n"; // "1"
std::cout << "(void*)&A::f " << (void*)&A::f << "\n"; // "0x4084b0" Here's what I was actually looking for.
std::cout << "(void*)&B::f " << (void*)&B::f << "\n"; // "0x4084bc" Good - the B::f differs from A::f as it should
std::cout << "(void*)&C::f " << (void*)&C::f << "\n"; // "0x4084b0" Perfect.
std::cout << "(void*)&A::f == (void*)&B::f " << ((void*)&A::f == (void*)&B::f) << "\n"; // "0"
std::cout << "(void*)&A::f == (void*)&C::f " << ((void*)&A::f == (void*)&C::f) << "\n"; // "1"
std::cout << "(void*)&B::f == (void*)&C::f " << ((void*)&B::f == (void*)&C::f) << "\n"; // "0" These are the comparison results I want
So my question is marked by DANGER in the code above. Why does &A::f == &B::f if &f != &g? Is there a way to do the comparison I want without casting to void* (which gives off noisy compiler warnings thanks to -Wpmf-conversions)?
I am working on the latest revision of the C++ programming language (think it's 5) and run into a problem with g++ version 5.2.
My code is a variation of Small_size template from chap 24.
#include <iostream>
template<int N>
bool is_small ()
{
std::cerr << sizeof(N) << std::endl;
std::cerr << N << std::endl;
return N <= 255;
}
bool ism (int i_n)
{
return i_n <= 255;
}
int main ()
{
std::cout << "hallo welt" << std::endl;
std::cout << 0 << " " << is_small<0> << std::endl;
std::cout << 255 << " " <<is_small<255> << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000> << std::endl;
std::cout << 256 << " " << is_small<256> << std::endl;
std::cout << 256 << " " << ism(256) << std::endl;
std::cout << 256 << " " << (256 <= 255) << std::endl;
}
When I compile it, it's ok. But when I run the thing, it simply seems to be broken.
[cpp11#hydra src]$ cat ~/bin/g14
#!/bin/bash
g++-52 -std=c++14 "${1}.C" -L$LIBPATH -o "$1"
[cpp11#hydra src]$ g14 konzept_small
[cpp11#hydra src]$ ./konzept_small
hallo welt
0 1
255 1
-4100000000 1
256 1 //1
256 0
256 0
[cpp11#hydra src]$
My problem is that:
the result for 256 and higher is wrong. See comment //1
there is no output of the template code on cerr
I started with a version without the cerr, but got only the wrong template result.
I removed a constexpr from the template, but no change.
So I added as last step the cerr to see whats wrong.
Any ideas?
You are not calling is_small<N>, but just printing out its address. You need to change your code to
std::cout << 0 << " " << is_small<0>() << std::endl;
std::cout << 255 << " " <<is_small<255>() << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000>() << std::endl;
std::cout << 256 << " " << is_small<256>() << std::endl;
Note the added (). Not sure why you are getting the output you are though, are you sure you are running the same code you posted?
is_small is a function you should add the parenthesis :
change
std::cout << 0 << " " << is_small<0> << std::endl;
to this
std::cout << 0 << " " << is_small<0>() << std::endl;
It worked fine for me with this change