Identical code produces different output

  • Thread starter Thread starter tonyjeffs2
  • Start date Start date
T

tonyjeffs2

Main() prints to screen "The name is ", and then uses a function to
print "Ivor Horton".
Additionally, the function contains some debugging code, which outputs
the text "Name::getName()called".

When I download the files from the internet, the output is:
Name::getName()called
The name is Ivor Horton

My own faithfully transcribed version yields a garbled version:
The name is
Name::getName()called Ivor Horton

Even when I delete all my own text and replace every bit of it with
the author's version, it still comes out in the wrong order. I'm
baffled.
I'm using C++express and this is a CLR blank project in both cases.
I can't find any difference, but I must be missing something.
Any suggestions welcome
Thanks tony


____________________________________________________
Here is part of my class main():
____________________________________________________

int main(int argc, char* argv[])
{
Name myName("Ivor", "Horton");

// Retrieve and store the name in a local char array
char theName[12];
cout << "\nThe name is " << myName.getName(theName);
.. . .
}
___________________________________________________
Here is the function getName()
___________________________________________________

char* Name::getName(char* pName) const
{
assert(pName != 0); // Verify non-null argument

#ifdef FUNCTION_TRACE
// Trace function calls
cout << "\nName::getName() called.";
#endif

strcpy(pName, pFirstname);
strcat(pName, " "); // Append a space
return strcat(pName, pSurname); // Append second name and
return total
}
 
Main() prints to screen "The name is ", and then uses a function to
print "Ivor Horton".
Additionally, the function contains some debugging code, which outputs
the text "Name::getName()called".

When I download the files from the internet, the output is:
Name::getName()called
The name is Ivor Horton

My own faithfully transcribed version yields a garbled version:
The name is
Name::getName()called Ivor Horton

Even when I delete all my own text and replace every bit of it with
the author's version, it still comes out in the wrong order. I'm
baffled.
I'm using C++express and this is a CLR blank project in both cases.
I can't find any difference, but I must be missing something.

No, you're not.

There's no sequence point between (cout << "\nThe name is ") and
myName.getName(theName), so the compiler is free to evaluate them in either
order. Different compilers, different optimization settings, can all change
the output.

Welcome to the world of "implementation-dependent" behavior, where identical
code really does produce different output.

Any suggestions welcome
Thanks tony


____________________________________________________
Here is part of my class main():
____________________________________________________

int main(int argc, char* argv[])
{
Name myName("Ivor", "Horton");

// Retrieve and store the name in a local char array
char theName[12];
cout << "\nThe name is " << myName.getName(theName);
. . .
}
___________________________________________________
Here is the function getName()
___________________________________________________

char* Name::getName(char* pName) const
{
assert(pName != 0); // Verify non-null argument

#ifdef FUNCTION_TRACE
// Trace function calls
cout << "\nName::getName() called.";
#endif

strcpy(pName, pFirstname);
strcat(pName, " "); // Append a space
return strcat(pName, pSurname); // Append second name and
return total
}
 
Thanks Ben for the reply.

I'm using the same compiler in the same way with identical code.
Swapping the two identically named files Name.CPP swaps the fault -
it is permanantly attached to one file.
I've looked at them with a hex editor and they're (apparantly)
completely identical. Baffling!
I'll try and ignore it - it's too much of a side track I think- I'll
read about sequence points though.
My garbled output seems more in keeping with the sequence of execution
that I'd expect. It seems odd for a function to return its value
before executing the cout<< line.

much appreciated,
Tony
 
My garbled output seems more in keeping with the sequence of execution
that I'd expect.

Ah, but the point is, you shouldn't "expect" anything in particular,
because the order of evaluation of function arguments is unspecified.
It seems odd for a function to return its value
before executing the cout<< line.

The expression:

cout << x << y << z;

is translated into functional form as:

// Let f be operator<<
f(f(f(cout, x), y), z)

This preserves the left-to-right associativity of operator<<. For a
detailed look at the order of evaluation and sequence point issues for an
expression like this, see:

http://groups.google.com/group/microsoft.public.vc.language/msg/a5d3b3f8a4e3797c

You must always be careful when x, y, and z have side-effects. If you need
one to happen before another, you have to insert sequence points, e.g. if
the side-effects of y must occur before z is evaluated, this would be fine:

cout << x << y;
cout << z;
 
Thanks Ben for the reply.

I'm using the same compiler in the same way with identical code.
Swapping the two identically named files Name.CPP swaps the fault -
it is permanantly attached to one file.
I've looked at them with a hex editor and they're (apparantly)
completely identical. Baffling!
I'll try and ignore it - it's too much of a side track I think- I'll
read about sequence points though.
My garbled output seems more in keeping with the sequence of execution
that I'd expect. It seems odd for a function to return its value
before executing the cout<< line.

Why?

Your line:
cout << "\nThe name is " << myName.getName(theName);

Is equivalent to:
char* t1 = myName.getName(theName);
ostream& t2 = cout << "\nThe name is ";
t2 << t1;

but the order of the first two lines is indeterminate.
 
Ben,Doug

Is the output of the following code similarly unpredictable?
could the output be either of :-
"Here is a number-> 77" and "77Here is a number-> " ?

_________________________________

int order()
{
cout<< "Here is a number-> ";
return 77;
}

void main()
{
cout<<order()<<endl;
}
 
Ben,Doug

Is the output of the following code similarly unpredictable?
could the output be either of :-
"Here is a number-> 77" and "77Here is a number-> " ?

_________________________________

int order()
{
cout<< "Here is a number-> ";
return 77;
}

void main()
{
cout<<order()<<endl;
}

The output will always be:

Here is a number-> 77

There is a sequence point between statements, at function entry (for the
function's arguments), and at function exit (that's not an exhaustive
list), so when order() is called, its cout statement executes to
completion, and since order() must be evaluated before your cout statement
in main can print order()'s return value, the output is deterministic.
IIRC, manipulators such as endl are actually function pointers, so it works
out like this:

operator<<(operator<<(cout, order()), endl);

Now, the order of evaluation of cout, order(), and endl is unspecified, but
"evaluating" the reference to cout and the function pointer endl has no
effect, and the only one with side-effects is order(). So, the order of
evaluation of these arguments doesn't matter here, because the only one
whose evaluation amounts to anything is order(). So how does endl work?
Well, operator<< is overloaded on manipulators, so you end up in something
like this when you print endl:

ostream&
operator<<(ostream& os, manip_type manip)
{
return manip(os);
}

ostream& endl(ostream& os)
{
os << '\n';
flush(os);
return os;
}

Do you see how this approach avoids the problem you presented in your
original message?
 
I think I need to read all your posts again with a clearer more awake
head, which I'll do.
I'm probably offline for a day,
For now I'm going to doodle with the code...

Thanks again
Tony
 
Doug, Ben,
I understand it :)

cout<<"Here is an integfer->"<<order()

The two output operations must be carried out in left to right order,
but the calculation of those two outputs can be carried out in any
order. Unfortunately order() contains another cout<<, which would
happen whenever the return value of order() is being calculated.

I woke up at 4 am with the answer. It's now 5 a.m.

Many thanks

Tony
 
Back
Top