🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

2 total messages Started by rjc Fri, 17 Mar 1989 21:50
G++ 1.34.1 named return values (no fix)
#1759
Author: rjc
Date: Fri, 17 Mar 1989 21:50
94 lines
2435 bytes
rjc@cs.ucla.edu
Vax 8350, Ultrix 2.2-1 System #4
G++ 1.34.1 (plus patched cplus-decl.c) Gcc 1.34

>[ Patch from Michael for cplus-decl.c ... ]
>  
>yahi% 
>================================================================
>Here is the test program which now compiles:
>
>struct A {
>	int i;
>	A(int x) { printf("A(%d)\n", x); i = x; };
>	A(A& x) { printf("A(A& x), x.i == %d\n", x.i); i = x.i; };
>	~A(void) { printf("~A(%d)\n", i); };
>	void operator += (A& x) { printf("+=(%d, %d)\n", i, x.i); i += x.i; };
>};
>
>A foo (void) return tmp = 4;
>{
>	printf("foo(void), tmp.i == %d\n", tmp.i);
>	return tmp;
>}
>
>main()
>{
>	A bar = 5;
>	bar += foo();
>	printf("main(), bar.i == %d\n", bar.i);
>}
>================================================================
>And here are the results:
>
>yahi% a.out
>A(5)
>A(4)			<- ******** ~A() never called
>foo(void), tmp.i == 4
>A(A& x), x.i == 4	<- ******** Shouldn't be called
>+=(5, 4)
>~A(4)
>main(), bar.i == 9
>~A(9)
>yahi% 
>================================================================
>
>Michael

Michael,

Yes, the patch allows the test program to compile.  Unfortunately, the
code that is produced is badly broken.  You can see in the above output
that A(A&) is called on return from foo().  This is not supposed to
happen with a named return (as I understand it).  This is not too bad,
just the same old inefficiency that we have been suffering with up to
now.  The *big* problem is that ~A() is not called for the `tmp' in foo(),
but only for the copy produced by the call to A(A&) on return from foo().

I an not familiar with the interals of g++, so I cannot provide a fix.

Thanks,

rob collins
(rjc@cs.ucla.edu)




i
n
e
w
s

i
s

b
r
a
i
n

d
a
m
a
g
e
d

-------------------------------------------------------------------------------
rjc@cs.ucla.edu
This is what happens when I sit on my keyboard: AISBDFAORI:KHGEDSYTFBFISKVDJ MN
Next week:  what happens when I throw my keyboard out the window!
G++ 1.34.1 named return values (and related 1.34.1 problems)
#1767
Author: Doug Lea
Date: Sat, 18 Mar 1989 13:39
96 lines
3193 bytes
I think Michael's documentation was wrong (or at least misleading). If
you have a named return value, you should *only* return via `return'
or by falling-off-the-edge. (Otherwise, in your example, it says to
make tmp out of itself using A(A&), which is not very sensible.)  See
below. [Anyone wanting further rationale for this construct should see
my recent comp.lang.c++ postings.]

A few other notes about my experience with 1.34.1+ (1.34.1 plus Michael's
2 posted patches) on a vax750, 4.3BSD:

The -felide-constructors switch seems buggy.  All libg++ problems I've
been able to diagnose when testing this switch appear due to the kind
of local-variable-trashing behavior shown below.  Note, however, that
constructs both of the form `var a = fun()' and `var a(fun())' now, in
1.34.1, produce the same results (no temps!) with or without this switch.

Using the -fsave-memoized switch also seems buggy. Several libg++
tests (test5, intList.cc) fail to compile with this switch.

By the way, in the example, if you #include <stream.h>, you ought to
use `cout.form(...)' (or `cout << form(...)') instead of `printf' to
ensure proper flushing of output on program termination (on most
machines, this apparently only matters if you are redirecting output).


-Doug

------ file A.cc (a revision of rjc's example)

#include <stream.h>

struct A {
	int i;
	A(int x) { cout.form("A(%d)\n", x); i = x; };
	A(A& x) { cout.form("A(A& x), x.i == %d\n", x.i); i = x.i; };
	~A(void) { cout.form("~A(%d)\n", i); };
	void operator += (A& x) { cout.form("+=(%d, %d)\n", i, x.i); i += x.i; };
};

A foo () return tmp(4); // essentially equivalent to `tmp=4', 
                        // but explicitly use a constr. for clarity!
{
	cout.form("foo(void), tmp.i == %d\n", tmp.i);
	return;             // *not* `return tmp'
}

main()
{
	A bar = 5;
	bar += foo();
	cout.form("main(), bar.i == %d\n", bar.i);
    A baz = foo();
	cout.form("main(), baz.i == %d\n", baz.i);
    A baz_con(foo());
	cout.form("main(), baz_con.i == %d\n", baz_con.i);
}

-------- A correct compile/run without -felide-constructors

R>g++ -g -O -finline-functions A.cc
R>a.out
A(5)
A(4)
foo(void), tmp.i == 4
+=(5, 4)
~A(4)
main(), bar.i == 9
A(4)
foo(void), tmp.i == 4
main(), baz.i == 4
A(4)
foo(void), tmp.i == 4
main(), baz_con.i == 4
~A(4)
~A(4)
~A(9)

----------- with -felide-constructors

R>g++ -g -O -finline-functions -felide-constructors A.cc
R>a.out
A(5)
A(4)
foo(void), tmp.i == 4
+=(4, 4)                  # `bar' is trashed!
main(), bar.i == 8
A(4)
foo(void), tmp.i == 4
main(), baz.i == 4
A(4)
foo(void), tmp.i == 4
main(), baz_con.i == 4
~A(4)
~A(4)
~A(8)
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads