Re: dup2
On 24/04/14 11:43, Jorgen Grahn wrote:
On Wed, 2014-04-23, Paul N wrote:
On Tuesday, 22 April 2014 09:35:06 UTC+1, Hongliang Wang wrote:
[snipped because I cannot be bothered to fix the formatting]
Other people have explained this, but perhaps not clearly enough, so
I'll have a go.
In main, the object is brought into existence, but it then is
destroyed without the program doing anything to it. Strange as it may
seem, this means that the compiler is allowed to not create the object
at all. So you don't get the side effects from the constructor and the
destructor that you were hoping for.
Huh? Then how can the pattern with RAII mutex locks work?
void foo()
{
Lock lock(some_mutex);
do_stuff_that_needs_locking();
}
I've always assumed the compiler must obey (create 'lock', and do it
before calling the other function) in this case, not take a chance on
the constructor having no side effects. (Modulo the as-if rule, of
course.)
(I'm vaguely aware that copy construction is a special case and that
it's a Bad Idea to treat that one as any other function.)
/Jorgen
It all depends on observable effects - accessing volatiles, calls to
externally defined functions, exiting the program, and inline assembly.
If the compiler knows for sure that a particular expression (including
the construction of an object) does not have any influence on the
observable effects of the program, then it can remove that expression.
And if that means all actions on a variable is removed, then the
variable can be removed.
But if the compiler is in any doubt about the observable effects, then
it needs to generate the code in the order guaranteed to follow those
observable effects. So if Lock's constructor has such effects (and it
almost certainly will, to be of much use), then your lock gets created.
And if do_stuff_that_needs_locking() has any such effects (ant it
almost certainly will, or you wouldn't need the lock), it happens after
the Lock is created and before it is destroyed.
It is possible for things to be re-arranged, however. If you had this:
int protectedData;
static void do_stuff_that_needs_locking() {
int x = 0;
for (int i = 0; i < 1000; i++) {
x += i;
}
protectedData = x;
}
Then the compiler /could/ generate this:
void foo() {
int x = 0;
for (int i = 0; i < 1000; i++) {
x += i;
}
Lock lock(some_mutex);
protectedData = x;
// Destruct lock
}