Jump to content
  • Advertisement
Sign in to follow this  
Servant of the Lord

Unity Answers to Washu's quiz #1?

This topic is 3402 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I just came across Washu's C++ quiz, when I skimmed through this GDNet thread, and I just finished answering the questions. Can someone check my answers? (He didn't provide the answers for the first quiz)
Quote:
Given the following three lines of code, answer these questions.
int* p = new int[10];
int* j = p + 11;
int* k = p + 10;
1.A) Is the behavior of the second line well defined? 1.B) If the behavior second line is well defined, where does the pointer point to? 1.C) What are some of the legal operations that can be performed on the third pointer?
1.A) Yes 1.B) It points to the location immediately after the int array (The address of 'p' + sizeof(int)*10). What's contained there, on the other hand, could be utter gibberish. 1.C) You can use any pointer manipulation operators on it, like any other pointer. (add, subtract, multiply, divide, etc...)
Quote:
2) What output should the following line of code product?
int a = 10;
std::cout<<a<<a++<<--a;
2) 10 9 9
Quote:
3) Assuming the function called in the following block of code has no default parameters, how many parameters does it take? Which objects are passed to it? f((a, b, c), d, e, ((g, h), i));
3) It takes four parameters. (a, d, e, and g)
Quote:
4) Assuming the function called in the following block of code takes an A* and a B*, what is bad about the code?
f(new A(), new B());
4) What's bad is that you'll leak memory unless 'f' knows to free both 'A' and 'B', because the scope of A and B will end immediately following the function call, and so the user has no chance to free it themselves. 'f' must do the freeing (or else keep pointers to them to free later, depending on what the function is used for), and 'f' must also do the error checking, in case 'new' fails.
I know I made a few mistakes, from reading this, but did I get any of the other questions right?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
1.A) Yes

Actually, I don't think so. You're allowed to point one past the end of the array, but not past that. The last element of the array is (p + 9). So one past is (p + 10). (p + 11) is undefined.

Quote:
1.C) You can use any pointer manipulation operators on it, like any other pointer. (add, subtract, multiply, divide, etc...)

You can't multiply/divide pointers.

Quote:
2) 10 9 9

Isn't this undefined behaviour? a, a++ and --a could be evaluated in any order.

Quote:
4) What's bad is that you'll leak memory unless 'f' knows to free both 'A' and 'B', because the scope of A and B will end immediately following the function call, and so the user has no chance to free it themselves. 'f' must do the freeing (or else keep pointers to them to free later, depending on what the function is used for), and 'f' must also do the error checking, in case 'new' fails.

There's no error checking that can be done. If new fails, an exception is thrown, and memory will leak if either of the allocations succeeded before throwing. That's why this is bad - because you have a 50% chance of leaking memory if either allocation fails.

Share this post


Link to post
Share on other sites
The answers are here and perhaps in the comments here. Favor the first link. Sadly, you got most of them wrong (or at least partially so) :( But most people do, so its okay.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sc4Freak
Quote:
2) 10 9 9

Isn't this undefined behaviour? a, a++ and --a could be evaluated in any order.

Correct -- there are no sequence points seperating the evaluation of a, a++, and --a. Since a is int, this violates the rule of not modifying integral types multiple times between sequence points, the penalty is UB.

Were "a", say, a non-pointer iterator type instead, you'd merely get an unspecified order of evaluation.

Operator precedence is (almost) entirely unrelated to evaluation order -- it just specifies that a+b+c is evaluated as operator+( operator+(a,b), c ) rather than operator+( a , operator+(b,c) ). Only a few operators define any extra sequence points: the intrinsic ",", "&&", "||", and "?:" operators. These only apply to the intrinsic version -- overloaded versions need not apply.

To consider a( b(), c() );, the only (relevant) sequence point is that a() will be executed sometime after both b() and c() have.

Quote:
From the C++ Standard (ISO/IEC 14882:2003), page 65, with various styling added

5 Expressions [expr]

...

4 Except where noted, the order of evaluation of operands of individual operators and subexpressions of indi-
vidual expressions, and the order in which side effects take place, is unspecified.53) Between the previous
and next sequence point a scalar object shall have its stored value modified at most once by the evaluation
of an expression.
Furthermore, the prior value shall be accessed only to determine the value to be stored.
The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined
. [Example:
    i = v[i++];  // the behavior is unspecified
i = 7, i++, i++; // i becomes 9 [MM: intrinsic operator, adds sequence points]
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented

—end example]


[Edited by - MaulingMonkey on January 23, 2009 7:25:37 PM]

Share this post


Link to post
Share on other sites
Disclaimer: My answers might be wrong.

Quote:
Given the following three lines of code, answer these questions.
int* p = new int[10];
int* j = p + 11;
int* k = p + 10;

1.A) Is the behavior of the second line well defined?
1.B) If the behavior second line is well defined, where does the pointer point to?
1.C) What are some of the legal operations that can be performed on the third pointer?


1.A) No
1.B) It is not well defined, it is out of the bounds of the deferenceable range + 1.
1.C) All pointer operations sans dereferencing.

Quote:
2) What output should the following line of code product?
int a = 10;
std::cout<<a<<a++<<--a;


2) Three numbers, values consisting of 10 and 9. Specifics are unspecified since order of evaluation is unspecified.

Edit: Well apparently this is undefined as opposed to unspecified.

Quote:
3) Assuming the function called in the following block of code has no default parameters, how many parameters does it take? Which objects are passed to it?
f((a, b, c), d, e, ((g, h), i));

3) It takes four parameters: c, d, e, i

Quote:
4) Assuming the function called in the following block of code takes an A* and a B*, what is bad about the code?
f(new A(), new B());

4) If one allocation fails then an exception is thrown, if the the other allocation had already succeeded then memory is leaked.

Share this post


Link to post
Share on other sites
Quote:
Original post by dmatter
Quote:
2) What output should the following line of code product?
int a = 10;
std::cout<<a<<a++<<--a;


2) Three numbers, values consisting of 10 and 9. Specifics are unspecified since order of evaluation is unspecified.

Were it not UB, it could be 11 as well. Consider the case where a++, then a, then --a are evaluated.

Quote:
Quote:
3) Assuming the function called in the following block of code has no default parameters, how many parameters does it take? Which objects are passed to it?
f((a, b, c), d, e, ((g, h), i));

3) It takes four parameters: c, d, e, i

Good catch.

Share this post


Link to post
Share on other sites
Thanks for linking to the answers.

I couldn't remember whether the comma operator evaluates both objects, and returns the first, or evaluates both, and returns the second. Apparently it's the second. (Question 3) The others I just flat out got wrong.

However, I must question Washu's answer to #2.

Quote:
2. This line of code has two problems. The first is that the order in which function parameters are evaluated is unspecified. As such, a, a++, and --a can all be processed in any order. However, there is a bigger problem. We are not allowed to modify the same object more than once between sequence points, yet in this case, we have done so twice. As such the behavior of this code is undefined. It could legally obliterate the universe.

std::cout isn't really a function. It's overloading the << operator, and the << operator has a defined order of which objects are evaluated first.

It'd evaluate to:
(((std::cout << a) << a++) << --a);

With each pair of parapheses returning a reference to std::out. (Like here)

It'd print 10, 10, 10 every time, regardless of compiler. (I said 10 9 9, because like the comma operator, I mistakenly swapped the order of evaluation in my mind)

Isn't that correct?

[Edit:] Others posted before I finished my post, so my response as already been broken before it even became public. [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
Quote:
Original post by dmatter
2) Three numbers, values consisting of 10 and 9. Specifics are unspecified since order of evaluation is unspecified.

Were it not UB, it could be 11 as well. Consider the case where a++, then a, then --a are evaluated.
Oops, thanks for the catch, 11 slipped by me.

Share this post


Link to post
Share on other sites
Quote:
Original post by Servant of the Lord
It'd print 10, 10, 10 every time, regardless of compiler. (I said 10 9 9, because like the comma operator, I mistakenly swapped the order of evaluation in my mind)

I'm bored.

MSVC 9, Release: 9910
MSVC 9, Debug: 10910
MSVC 8, Release: 9910
MSVC 8, Debug: 10910
MSVC 7.1, Release: 9910
MSVC 7.1, Debug: 10910
g++ 3.4.4 cygming -O0: 101010
g++ 3.4.4 cygming -O1: 101010
g++ 3.4.4 cygming -O2: 101010
g++ 3.4.4 cygming -O3: 101010
g++ 3.4.4 cygming -Os: 101010
Borland Turbo C++ 2006, Debug: 1099
Borland Turbo C++ 2006, -O1: 1099
Borland Turbo C++ 2006, -O2: 1099


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!