F
Frank Chang
Andy, please read post 9 in this thread. Thank you.
One should code by the standard not by what compilerFrank said:Andy, I know what the c++ standard says about the fact that that all
evaluation of function arguments takes place before execution of any
expressions of any expressions or statements in the the function body.
This is very similar to way the Scheme interpreter evaluator
functions(see Structure and Interpretaion of Computer Program by Harold
Abelson and Gerald Sussman). But as "almost anonymous" says, what the
C++ standard and the C++ compiler do are actually two different things.
This is the result of UB. Why is it so hard for you to understand? As"The failure occurs inside the TestFunction and not at the call to
TestFunction. This is with the Metrowerks compiler but I'm sure it's
true for all compilers.
that is how the code is compiled by your compiler on your platformThe dereference does not occur at the call site because it's not
deferenced at the point. Instead, because it's a reference parameter,
the address is pushed onto the stack.
Even if every single C++ compiler would generate the same machine codeIf the parameter was not a reference parameter then you would be
right... the dereference would occur at the call."
So, in reality , the argument addresses are pushed on the stack without
being deferenced. I guess the best way to resolve our difference is to
look at assembly code that the C++ compiler generates.
Victor said:Rolf said:Victor Bazarov wrote:
Yes, a valid program shouldn't "crash". And I bet there are programs
that
just do not crash. They report critical situations, work their way
out of
them, and so on.
Never happens and is the reason why people invent
"safe" languages like Java et al.
No trolling here, please.
I don't see why this would be trolling. One reason why Java [...]
That's what I call trolling. Java is OFF-f#@*ng-TOPIC, yet you just
continued a discussion on it. He successfully trolled you into this.
Frank said:Andy, please read post 9 in this thread. Thank you.
Frank said:NULL references are unbelievably easy in C++...
someClass* instance = SomeOperation();
Test(*instance );
And these are cases where the compiler is non-conforming.Frank said:Andy, I know what the c++ standard says about the fact that that all
evaluation of function arguments takes place before execution of any
expressions of any expressions or statements in the the function body.
This is very similar to way the Scheme interpreter evaluator
functions(see Structure and Interpretaion of Computer Program by Harold
Abelson and Gerald Sussman). But as "almost anonymous" says, what the
C++ standard and the C++ compiler do are actually two different things.
"The failure occurs inside the TestFunction and not at the call to
TestFunction. This is with the Metrowerks compiler but I'm sure it's
true for all compilers.
The dereference does not occur at the call site because it's not
deferenced at the point. Instead, because it's a reference parameter,
the address is pushed onto the stack.
If the parameter was not a reference parameter then you would be
right... the dereference would occur at the call."
So, in reality , the argument addresses are pushed on the stack without
being deferenced.
I guess the best way to resolve our difference is to
look at assembly code that the C++ compiler generates.
Victor said:Rolf said:Victor Bazarov wrote:
Yes, a valid program shouldn't "crash". And I bet there are programs
that
just do not crash. They report critical situations, work their way out
of them, and so on.
Never happens and is the reason why people invent
"safe" languages like Java et al.
No trolling here, please.
I don't see why this would be trolling. One reason why Java [...]
That's what I call trolling. Java is OFF-f#@*ng-TOPIC,
yet you just continued a discussion on it. He successfully trolled you
into this.
OK, here you go
#include <iostream>
int main() {
std::cout << 'H' << 'e' << 'l' << 'l' << 'o'
<< ' ' << 'w' << 'o' << 'r' << 'l' << 'd' << '\n';
}
Better now?
I don't understand this argument.
What's the difference between this and someone inadvertantly doing:
Test(someClass* p)
{
p->doSomething();
}
...
someClass* instance = SomeOperation();
Test(instance);
or even worse:
Test(SomeOperation()); // We assume Test will check that that pointer
is ok
Both cases dereference a pointer that's never been checked for
non-zero. Are you saying that people are careless when dereferencing a
pointer using * but not careless when using a pointer via ->? That's
not consistent with my observations of people's code. I've seen much
sloppier handling of pointers in code that takes pointers than in code
calling routines taking references.
ur passing objects as args..
Frank, if you program according to the standard i.e. by assuming thatevaluation of function arguments takes place before execution of any
expressions of any expressions or statements in the the function body.
This is very similar to way the Scheme interpreter evaluator
functions(see Structure and Interpretaion of Computer Program by Harold
Abelson and Gerald Sussman). But as "almost anonymous" says, what the
C++ standard and the C++ compiler do are actually two different things.
"The failure occurs inside the TestFunction and not at the call to
TestFunction. This is with the Metrowerks compiler but I'm sure it's
true for all compilers.
The dereference does not occur at the call site because it's not
deferenced at the point. Instead, because it's a reference parameter,
the address is pushed onto the stack.
If the parameter was not a reference parameter then you would be
right... the dereference would occur at the call."
So, in reality , the argument addresses are pushed on the stack without
being deferenced. I guess the best way to resolve our difference is to
look at assembly code that the C++ compiler generates.
Earl said:Passing by pointer comes from the C attitude:
void useAnInt( int x )
{
do_something_with_x( x );
}
void setAnInt( int * x_address )
{
*x_address = someValue();
}
Now from the code that calls the function it looks clear
whether or not the function is likely to modify (set) your value.
void callingFunc()
{
int x;
setAnInt( &x ); /* will be setting this value to something */
useAnInt( x ); /* x will not be changed by this function */
}
Those who are taught "C first" will probably learn this even before
they use larger structs, which they might
want to pass as a pointer even if it is not going to be modified for
efficiency.
When they move over to C++ and learn about references, there is a
feeling of discomfort.
You can pass a function thus useAnInt( x ); and you won't know if
useAnInt() might modify the x without
looking at the function, whereas setAnInt( &x ) is likely to because
you passed it by address.
The difference is that, when inside a function, if the argument is a reference,
you can rely upon it being a real object.#include <iostream>cat main.cc
void f(const int& r) {
std::cout << "r = " << r << std::endl;
}
int main(int argc, char* argv[]) {
int* p = 0;
int& r = *p;
f(r);
Ram said:Apart from accessing the object's member's with dot (.) notation, it
delegates the responsibility of passing a valid object to the caller.
When one passes a pointer, that may not or may be a NULL (in which case
you aren't allowed to de-reference it). But with a reference and in a
valid sequence you are guaranteed that you have a valid object. That
can't be said for a pointer argument. The NULL pointer itself may be a
valid argument.
I disagree. If I call a function that takes a pointer, I never pass a
null pointer unless the documentation of the function explicitly says
that it accepts a null pointer _and_ that it handles it the way I
want.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.