• entries
146
436
• views
197901

Another C++ quiz, the forth in fact.

352 views

A lot of code in this one, but you guys should be able to handle it, it is all quite easy.

struct C;void f(C* p);struct C {	int c;	C() : c(1) { f(this); }};const C obj;void f(C* p) {	int i = obj.c << 2;             //1	p->c = i;                       //2	std::cout<< obj.c << std::endl; //3}

1. What is the value of i after the first numbered line is evaluated?
2. What is the value of p->c after the second numbered line is evaluated?
3. What does the third numbered line print?

struct X {	operator int() { return 314159; }};struct Y {	operator X() { return X(); }};Y y;int i = y;     //1int j = X(y);  //2

Without compiling, answer the following questions:
4. What should you expect the compiler to do on the first numbered line? Why?
5. What should you expect the value of j to be after the second numbered line is evaluated? Why?

struct Z {	Z() {}	explicit Z(int) {}};Z z1 = 1;                 //1Z z2 = static_cast(1); //2

Without compiling, answer the following questions:
6. What should you expect the compiler to do on the first and second numbered lines? Why?

struct Base {	virtual ~Base() {}};struct Derived : Base {	~Derived() {}};typedef Base Base2;Derived d;Base* p = &d;void f() {	d.Base::~Base();    //1	p->~Base();         //2	p->~Base2();        //3	p->Base2::~Base();  //4	p->Base2::~Base2(); //5}

Without compiling, answer the following questions:
7. What should you expect the behavior of each of the numbered lines, irrespective of the other lines, to be?

1) 4 // operator << should be const safe, 1 << 2 (0001 -> 0100) = 4
2) 4
3) 4
4) Complain about lack of conversion, because the compiler will not make a leap of calling on the operator X for the type case.
5) Should invoke a copy constructor, as Y is automatically type cast to X, and then returns 314159 from the int conversion. j = 314159

6,7) Both were covered in chat. so not answering.

Edit: changed answers 1-3 because of type that was fixed.

#1: Accessing the member of a const object during initialization (except either directly or indirectly via the this pointer - which this is not) results in undefined values.
#2: Since i has undefined values, p->c now does too, although before the assignment it's result would have been defined.
#3: As per #1, undefined.

#4: Fails to compile, would require two implicit casts (which just dosn't work).
#5: 314159. In this case, we have an explicit case, which reduces the number of implicit casts required to get to int to 1 (which does work)

#6: The first line fails to compile, as it requires implicit construction. The second line compiles due to the explicit cast.
#7.1: calls Base's destructor, well defined.
#7.2: calls Derived's destructor, well defined
#7.3: calls Derived's destructor, well defined
#7.4: calls Base's destructor, well defined
#7.5: Error, there is no destructor with that name in Base
#7 Appendium: Both VS2005 and GC4.0.0 compile #5, as calling Base's destructor. Also note that #2 will affect #3 if you try to compile it all at once for verification - but, both compiled individually, will clearly call Derived's destructor.

Posted without looking at the previous comments first

1) Becomes 1 << 2 as the initializer list is executed before the body of the constructor. That would make i = 4.

2) 4

3) 1 as its a different 'C' to the one used in the previous two statements.

4) I don't really know, but I've got a feeling it might do some odd conversion and end up with 314159. But thats just a guess.

5) You'd get 314159 as it'd call the operator int() function. Not sure what the default copy constructor would do with the 'y' though.

6) First line is okay, second line is a compile error due to the explicit part?

7) First line will call the ~derived() destructor but thats it - it doesn't call the base destructor. Second line calls the base destructor, third line attempts to do the same (not sure about that though). None of them actually release/free the allocated memory though. Fourth line suggests error to me, fifth line seems okay though. Although, I'm not 100% sure what (if anything bad) will happen on calling the same destructor multiple times [oh]

Anyway, hopefully I'm not gonna look too stupid [smile]

Jack

Quote:
 Original post by Washu A lot of code in this one, but you guys should be able to handle it, it is all quite easy.

I'm not so sure... easy can be deceptive.

1: What is the value of i after the first numbered line is evaluated? 1
2: What is the value of p->c after the second numbered line is evaluated? 4
3: What does the third numbered line print? 4... I hope.

4: Complain. I dont think it will look deeper than the same class for conversions.
5: 314159. X(y) is X( y.operator X() ) is X( const X & ). X::operator int() on the copyied X is invoked, causing the value 314159 to be assinged to j.

6.1: Error. I think. :/
2.2: Should be fine...

(taking each seperatly, not as a chain of desconstuctor callings )

7.1: partial decontruction
7.2: full "
7.3: I think it may allow it (typedef::type or type::typdef), if so should be full deconstruction
7.4: same
7.5: same

:/ Not feeling very sure at all.

1. 4
2. undefined
3. 4

4. Spit out a conversion error, since the compiler would have to do 2 implic casts
5. 314159, since we are doing an operator int on an X, which is defined an implicit

6.1. error, there is no implicit constructor that takes an integer
6.2. explicitally create a Z, then copy construct it to z2

7.1. Call base's destructor
7.2. call the base destructor, then the derived
7.3. genrate an error, since there is no function ~base2()
7.4. call the base destructor
7.5. error again, same as 7.3