-
Re: try to stump me on C++
Quote:
Originally Posted by TheCPUWizard
It actually IS very well defined behavior, although one that some (pre-2003) compilers did not conform to the standard.
Hmm, in that case I will have an educated guess and go back to my C roots, where all global data was, by default, initialised to zero. I would therefore think that C++ memsets such global data to zero before any user defined initialisation code is run. Therefore I would guess that X will already be zero when it is returned by f().
-
Re: try to stump me on C++
How should this not be allowed to compile?
Code:
CSomeClass obj; // Not allowed
Code:
CSomeClass * pObj = new CSomeClass; // Ok
-
Re: try to stump me on C++
Quote:
Originally Posted by ch0co
Thought this topic was about you ?? now were have you gone ?? lol; no traces of your messages again.
I hope he'll be coming back.
Quote:
Originally Posted by ch0co
I'm new to C++ (still struggling with it for 2months now :D) what are POD types?? and what is the big deal about this copy constructors??
POD means plain-old-data, which is (more or less) any type that can safely be copied using the memcpy function. For example, Windows' POINT structure is a POD type, but std::string is not a POD type.
The big deal with the copy constructors (and assignment operators) is the fact that many many objects will have them, so it is important to get them right consistently.
-
Re: try to stump me on C++
Glad to see that the "post in under 24 hours or be subject to sarcasm" rule is still in effect. I'm still here, but have a life so, sorry can't fill up the page with pseudo hi-jacking all day. Anyway, GUYS, I can't believe after the careful scrutiny of my original answer, you didn't see that I had completely misread the code...I was just plain wrong! The original code says:
*this = x;
For some strange reason I saw:
this = &x;
...now you see the memory leak that was so obvious to me, yet so not there. Of course, that code is illegal, but the equivalent is just a small difference with a cast or two and perhaps a void* in there.
Anyway, exterminator, thanks for your comments, even though it's sort of moot by the time you realize I was starting with a bad assumption to begin with. Regarding *this, of course, you'd never (or very rarely) want to change the pointer itself (indirectly - the only way). And, modifying the dereferenced *this, as you know, has some specific, common uses, so I think most C++ coders would recommend not using *this unless you have to as there is almost always another way around it that is clearer, and less error prone.
If I haven't answered somebody else please follow up 'cause I pretty much skimmed the mess you see before you once it started getting livelier. Frankly, I don't feel this thread is super-helpful to any other passers by because there is much miscommunication going on. Would be better to condense the info into something more concise and post it seperately.
BTW: "Effective C++" by Scott Meyers does cover the copy constructor/assignment operator stuff quite clearly...(oops, I cheated).
-
Re: try to stump me on C++
Also, again thanks to everyone who is responding. Still waiting for new and wonderful challenges....my interview is just hours away.
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
Anyway, GUYS, I can't believe after the careful scrutiny of my original answer, you didn't see that I had completely misread the code...
Because you said:
Quote:
Originally Posted by andersod2
Lot's of negative implications with modifying *this, and should almost never be done.
As you actually wrote "*" in front of "this" yourself, yet you had not noticed the "*"?
Especially as you responded to me saying that "*this = x" is the same as "operator=(x)", without you saying anything about misreading the code in your post #18.
:confused:
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
Also, again thanks to everyone who is responding. Still waiting for new and wonderful challenges....my interview is just hours away.
Post #52 in this thread. ;)
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
My comments were based on the assumption that the operation was possible, or that you didn't dereference the "this" pointer and were just casting away the uniqueness of everything to make it a legal operation.
Oh, when you said that you were thinking about:
That sentence makes a bit more sense now.
Quote:
Originally Posted by andersod2
If that were the case, then the same comments would be in effect, namely memory leak for sure, and possibly a program crash on destruction.
I'm fairly sure the effect of just overwriting the "this" pointer with the address of x would been the same as doing nothing at all in that function.
The "this" pointer is normally just implemented as a hidden parameter which is passed into the function and is effectively a local variable.
So overwriting the "this" pointer, if it were possible, would be like writing the following in C:
Code:
foo_foo(const foo* inThis, const foo* inX)
{
inThis = inX;
}
-
Re: try to stump me on C++
yes, like i said, much confusion going on, mostly on my part...that's what I get for "not cheating."
> I'm fairly sure the effect of just overwriting the "this" pointer with the
> address of x would been the same as doing nothing at all in that function.
True, in the case you gave, but the value of this is still the same for the class being referred to...so I was thinking something along the lines of modifying the "this" pointer directly (i.e. taking it's address). After cheating on that, though, the compiler tells me you can't take the address of this (not an l-value), so one would need a fancy schmancy way of creating the equivalent to "this = &x" ....in order to create a memory leak...good for us that C++ makes that difficult to do.
Ok, so in regard to Ejaz' problem....again with no cheating...I will have to say, um, make the constructor private, and overload the new operator. Seems like there is more than meets the eye there, but I could be wrong. If so, there could be a need to make CSomeClass a derived class, but I can't think of why at the moment.
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
Ok, so in regard to Ejaz' problem....again with no cheating...I will have to say, um, make the constructor private, and overload the new operator. Seems like there is more than meets the eye there, but I could be wrong. If so, there could be a need to make CSomeClass a derived class, but I can't think of why at the moment.
Assuming no other code, making the destructor private should suffice.
-
Re: try to stump me on C++
Quote:
Originally Posted by Ejaz
How should this not be allowed to compile?
Code:
CSomeClass obj; // Not allowed
Code:
CSomeClass * pObj = new CSomeClass; // Ok
Along the same lines, but more general...
Is it possible to either:
1) Prevent an object from being created on the stack but allow creation on the "heap?"
2) Prevent an object from being created on the "heap" but allow it to be created on the stack?
If you answer yes for either or both, please provide an example....
[please dont let this degenerate to "heap" vs. "freestore", I admit to being loose with the terms...]
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
True, in the case you gave, but the value of this is still the same for the class being referred to...so I was thinking something along the lines of modifying the "this" pointer directly (i.e. taking it's address). After cheating on that, though, the compiler tells me you can't take the address of this (not an l-value), so one would need a fancy schmancy way of creating the equivalent to "this = &x" ....in order to create a memory leak...good for us that C++ makes that difficult to do.
I don't understand what you mean by "modifying the 'this' pointer directly (i.e. taking it's address)". In a typical C++ implementation the only "this" pointer is the hidden parameter passed into the function call, which only exists for the duration of the function call. How on earth would you create a memory leak just by modifying the value of that hidden parameter?
-
Re: try to stump me on C++
Quote:
Originally Posted by Plasmator
Assuming no other code, making the destructor private should suffice.
Correct :) However, for real world applications, a separate destruction mechanism would be required to deallocate the object.
-
Re: try to stump me on C++
How did the interview go?
-
Re: try to stump me on C++
> Is it possible to either:
> 1) Prevent an object from being created on the stack but allow creation
> on the "heap?"
> 2) Prevent an object from being created on the "heap" but allow it to be
> created on the stack?
Ok, for the sake of time I'm going to say yes on both counts, but I don't have time to give examples (not good ones anyway). Basically, your local variables are going to be on the stack, and your dynamic memory will be on the heap. So, as Plasmator revealed, I think the answer to Ejaz' problem fulfills the first one (though nobody said, whether my solution was wrong or right). For the second one, I will just say doing everything normal, except overload new and make it private. Kind of rushing through this, so I haven't given it enough thought.
> How on earth would you create a memory leak just by modifying the
> value of that hidden parameter?
I suppose that would depend on where the parameter came from originally. How is "this" obtained for purposes of pushing the parameter onto the stack? Is it just a matter of taking the address of the object in question? (I don't know) If not, I could imagine a scenario where usurping the address of "this" (in some strange manner) was capable of causing us to lose the address of the object altogether....maybe if "this" was in fact a global variable behind the scenes??... and was just pushed onto the stack as-is, under the assumption that programmers can't access it's address anyway (without trying hard). At any rate, it's not a very enlightening issue since I think we are agreed that it's a good thing that you can't modify "this" very easily. At the very least you've lost your object for the rest of the function call...doh!
-
Re: try to stump me on C++
Quote:
Originally Posted by Plasmator
Assuming no other code, making the destructor private should suffice.
Wouldn't you need a free() member function which deletes the object?
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
> Ok, for the sake of time I'm going to say yes on both counts, but I don't have time to give examples (not good ones anyway). Basically, your local variables are going to be on the stack, and your dynamic memory will be on the heap. So, as Plasmator revealed, I think the answer to Ejaz' problem fulfills the first one (though nobody said, whether my solution was wrong or right). For the second one, I will just say doing everything normal, except overload new and make it private. Kind of rushing through this, so I haven't given it enough thought.
Anybody else have comments before I reveal the answers (which were published in one of the most often referenced C++ books about 15 years ago...)??
-
Re: try to stump me on C++
A quick guess would be if you wanted to create on the heap but not on the stack would be to make the constructors private and supply some sort of 'Create' function?
-
Re: try to stump me on C++
For the the stack but not the heap, maybe declare an overloaded 'new' operator for the class but not define it?
-
Re: try to stump me on C++
Me bad :blush: :blush: :o :o :mad:
I left out the most important qualification (Doh!)...
"...without impacting the ability to create (in the other location) in any way".
My humble apologies..
-
Re: try to stump me on C++
I am going to take a rough guess and say the stl heap?
-
Re: try to stump me on C++
1) Prevent an object from being created on the stack but allow creation on the "heap?"
Code:
class SomeClass
{
private:
~SomeClass() {}
public:
void Destroy() { delete this; }
};
2) Prevent an object from being created on the "heap" but allow it to be created on the stack?
Code:
class SomeClass
{
private:
static void* operator new(size_t);
static void operator delete(void*);
static void* operator new[](size_t);
static void operator delete[](void*);
};
-
Re: try to stump me on C++
What would be the result of the following?
Or,
And no cheating ;)
-
Re: try to stump me on C++
is equivelent to
Undefined.
-
Re: try to stump me on C++
-
Re: try to stump me on C++
TheCPUWizard, did I get this right:
http://www.codeguru.com/forum/showpo...9&postcount=51
If not, what the *&%! is the answer. :D
-
Re: try to stump me on C++
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
Hmm, in that case I will have an educated guess and go back to my C roots, where all global data was, by default, initialised to zero. I would therefore think that C++ memsets such global data to zero before any user defined initialisation code is run. Therefore I would guess that X will already be zero when it is returned by f().
That is PART of the answer. The second part of the answer has to deal with how the computer detects if statics are initialized. I dont have the spec with my, but it is (as one would assume) a "one-shot" deal.
Therefore the first time the static is referenced (or at some prior point) the assignment (initialization, or construction) must happen once. However if the static is referred to during this process it does NOT happen again.
Many people give the wrong answer that it is a recursive call that will stack crash....
-
Re: try to stump me on C++
-
Re: try to stump me on C++
Hmm, confirmed. CPUWiz is correct. Looked into the standards today just to confirm/refresh my memory. [basic.start.init - 3.6.2/1] :(
The value would be 0 and is well defined. Here the variable with static storage duration is initialized twice. Static initialization happens either to be via zero initialization or constant initialization (if a constant is used). Anything else is dynamic initialization and static initialization happens before any dynamic initialization. There is no constant expression involved, so zero initialization for the static variable happens and it gets the value 0. The function call then forms the dynamic initialization part, wherein, X is dynamically initialized with the statically initialized value of X i.e. 0. And hence, X is 0.
Pasting the code below for reference:
Code:
static int X = f(); //dynamic initialization via the function call.
//static initialization/zero initialization already has happened before the function call
int f() { return X; } //effectively returns 0.
int main()
{
cout << X << end;
}
-
Re: try to stump me on C++
So ...
Code:
#include <iostream>
int f();
static int X = f();
int f() { return X + 1; }
int main()
{
cout << X << end;
}
and
Code:
#include <iostream>
int f();
static int X = f();
int f() { return X++; }
int main()
{
cout << X << end;
}
would be even more fun!
-
Re: try to stump me on C++
Quote:
Originally Posted by JohnW@Wessex
is equivelent to
Undefined.
Well, they both are undefined. Actually, if you read a variable twice in an expression where you also write it, the result is undefined.
Btw, I wonder what happened about the interview. :rolleyes:
-
Re: try to stump me on C++
Quote:
Originally Posted by Ejaz
Your link doesn't work.
-
Re: try to stump me on C++
http://www.research.att.com/~bs/bs_f...aluation-order
For some reason I had thought that the right hand side of the assignment is always evaluated before the left hand side of the assignment, in which case the result would have been well defined.
-
Re: try to stump me on C++
Quote:
Originally Posted by Ejaz
Yes, when I thought about it some more it makes sense.
Interestingly Visual Studio implements
v[i] = i++;
and
v[i] = ++i;
exactly as my initial gut reaction assumed they did.
Deliberate choice by Microsoft? Who knows.
I did read a comment on another forum that in C# these are well defined.
-
Re: try to stump me on C++
Quote:
Originally Posted by JohnW@Wessex
I did read a comment on another forum that in C# these are well defined.
Does that mean that in C# the right hand side is always evaluated before the left hand side (or is it perhaps the other way around)?
Wanders off to the C# forum ...
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
Wanders off to the C# forum ...
It wasn't on this site.
-
Re: try to stump me on C++
-
Re: try to stump me on C++
Quote:
Originally Posted by JohnW@Wessex
It wasn't on this site.
I didn't assume it was, I just went there to ask the question on this site. :)
-
Re: try to stump me on C++
It was in one of the comments here.
Not having ever coded in C# I have no knowledge on this aspect.
-
Re: try to stump me on C++
Below are two possibilities to instantiate and initialize a vector:
Code:
int pint[1234567] = {0};
and
Code:
int pint[1234567];
pint[0] = 0;
Why are those two possibilities equivalent? Or they are not equivalent?
-
Re: try to stump me on C++
Quote:
Originally Posted by aljodav
Below are two possibilities to instantiate and initialize a vector:
Not quite. In the first example you are initializing an array (vector is the name of an STL container, so you shouldn't use that word to refer to arrays). In the second example you are declaring an array and assigning, not initializing, its first element to 0.
-
Re: try to stump me on C++
> How did the interview go?
Thanks for asking arjay. I think it went well. We shall see soon enough I guess...I have another one coming up soon as well.
-
Re: try to stump me on C++
This question is about XOR operation.
Suppose you have two functions:
Code:
bool FooA(/*some parameter(s)*/)
{
//
// some code, including vectors (sorry Hermit, I mean array)
//
return some_boolean_value;
}
bool FooB(/*some parameter(s)*/)
{
//
// some code, including vectors (OMG, sorry again Hermit, I mean array)
//
return some_boolean_value;
}
And you want to compute :
Code:
bool b = FooA(/**/) ^ FooB(/**/);
The problem is that your computer keyboard IS NOT keying in the '^' symbol and, for some real reason, you cannot use any other keyboard. Which of the defines below would you use to implement the logical xor:
Code:
#define xor1 &&1!=
#define xor2 !=0==!
#define xor3 ==1==!
#define xor4 ==0!=
#define xor5 !=0&&
bool b1 = FooA(/**/) xor1 FooB(/**/);
bool b2 = FooA(/**/) xor2 FooB(/**/);
bool b3 = FooA(/**/) xor3 FooB(/**/);
bool b4 = FooA(/**/) xor4 FooB(/**/);
bool b5 = FooA(/**/) xor5 FooB(/**/);
Please, after answering this, buy a new keyboard.
-
Re: try to stump me on C++
heh, this is a funny one:
Ok, without cheating...an xor is the same as an inverter (electronics), or a half-adder without a carry....
So I would put:
bool x = FooA();
bool y = FooB();
bool b = (x || y) && (!(x && y));
...perhaps optimizable, but clear enough....fun! hey, some of those xor's look awefully equivalent at first glance....but a first glance is all they'll get :P
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
heh, this is a funny one:
Ok, without cheating...an xor is the same as an inverter (electronics)
Actually "!" (not) is an inverter (eg 7404 TTL chip). You can implement an inverter by using an XOR, and fixing one input at "1"/"true"/"high".
( I actually did this on a design in 1978-1979. Inverters came 6 to a chip, and XOR's 4 to a chip. I needs (6n+1) inverters, and (4n-1) XOR gates. By using the above technique I was able to eliminate one chip, which reduced the space requirements by approx 0.3 sq inches and also reduced the power draw.
[Sometimes I still miss the old days of TTL design. I remember well when it was "new technology" and was just making inroads against RTL and DTL]...
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
bool x = FooA();
bool y = FooB();
bool b = (x || y) && (!(x && y));
Yes! You got it right but, try this in a real program:
#define xor2 !=0==!
bool b2 = FooA(/**/) xor2 FooB(/**/);
and tell me which one is simpler. This one I got some time ago in Code Project's forum. :)
-
Re: try to stump me on C++
All the following functions will compile successfully... or not?
Code:
int FooA(/**/)
{
int n;
// n is used here...
float& f = (float)n;
// f and n are used here...
return n;
}
int FooB(/**/)
{
int n;
// n is used here...
float& f = n;
// f and n are used here...
return n;
}
int FooC(/**/)
{
int n;
// n is used here...
float& f = *(new float(n));
// f and n are used here...
delete &f;
return n;
}
int FooD(/**/)
{
int n;
// n is used here...
float& f = float(n);
// f and n are used here...
return n;
}
-
Re: try to stump me on C++
Quote:
Originally Posted by aljodav
tell me which one is simpler.
As you are returning booleans, why not use the logical boolean xor operator which C++ provides:
Code:
if(fooA() != fooB())
{
}
:)
-
Re: try to stump me on C++
Quote:
Originally Posted by aljodav
The problem is that your computer keyboard IS NOT keying in the '^' symbol and, for some real reason, you cannot use any other keyboard.
I wonder what direction the interview would take if you answered with either of these:
1. Use a trigraph sequence: ??'
2. ALT + 094
Do you think you'd get the job for being a smart ***? :rolleyes: