|nsCOMPtr|: is it time to remove the 'don't forward declare T hack'?




18 years ago
16 years ago


(Reporter: netscape, Assigned: john)


Dependency tree / graph

Firefox Tracking Flags

(Not tracked)


(Whiteboard: [FIX])


(3 attachments, 1 obsolete attachment)

I was trying to clean up circular jar requirement from bug 107289 and I ran
across this tidbit in nsCOMPtr.h:

    enum { _force_even_compliant_compilers_to_fail_ = sizeof(T) };
        The declaration above exists specifically to make |nsCOMPtr<T>| _not_
compile with only
        a forward declaration of |T|.  This should prevent Windows and Mac
engineers from
        breaking Solaris and other compilers that naturally have this behavior.
        <law@netscape.com> for inventing this specific trick.

        Of course, if you're using |nsCOMPtr| outside the scope of wanting to
compile on
        Solaris and old GCC, you probably want to remove the enum so you can
exploit forward

What exactly was the "tainting" problem and which compilers did it affect?
I believe the only compiler affected was gcc, which we dropped a few
weeks ago.  We could try removing this enum declaration and then putting an
nsCOMPtr with a forward-declaration into the tree and seeing if any tinderboxes
go red...
back to you chris.
Assignee: dougt → seawood
Priority: -- → P2
Target Milestone: --- → mozilla0.9.7
Target Milestone: mozilla0.9.7 → mozilla0.9.9
Target Milestone: mozilla0.9.9 → mozilla1.2
Last Resolved: 17 years ago
Resolution: --- → WONTFIX
Why nevermind?  We should fix this.  I'll take it if you want (although I won't
get to it immediately).
Assignee: seawood → dbaron
Priority: P2 → P1
Target Milestone: mozilla1.2alpha → Future
*** Bug 173154 has been marked as a duplicate of this bug. ***

Comment 7

17 years ago
Created attachment 102112 [details] [diff] [review]

This patch includes both nsCOMPtr<> and a short testcase for it in dlldeps.cpp
(a fictional class)
Comment on attachment 102112 [details] [diff] [review]

dlldeps.cpp is not built cross-platform.  Find a real test that's actually part
of the build, and that you've tested fails without the nsCOMPtr.h changes.

Comment 9

17 years ago
Created attachment 102113 [details] [diff] [review]
Patch #2

This one changes a file that is compiled on all platforms and which I have
tested does *not* work before and *does* work after the change.
Attachment #102112 - Attachment is obsolete: true
Comment on attachment 102113 [details] [diff] [review]
Patch #2

r=sicking assuming you've talked with scc about this and he's for it
Attachment #102113 - Flags: review+

Comment 12

17 years ago
Fix checked in.  Let's see what she does to ports, arrr.
Assignee: dbaron → jkeiser


17 years ago
Whiteboard: [FIX]

Comment 13

17 years ago
*sigh* OS/2 failed.  Will back out once BeOS picks up the change so we can see
what happens with that platform..

mkaply, what can we do about this?  IBM stopped supporting the OS/2 compiler a
year and a half ago (
).  Are there any other options?

bbaetz also points out that this means we will need the hack in nsCOMArray.

Comment 14

17 years ago
Fix backed out.  This is a serious issue.  As we start to use more and more
templates in our code, backwards platforms are going to hinder progress.
alecf: will we need this hack in nsCOMArray? I'm guessing yes, but I guess it
depends on exactly what part of this construct os2 was breaking on.
Oh, and one other thing I mentioned to jkeiser - when we do enable this again,
we should have an autoconf test which errors out if this won't compile, just to
make the requirements explicit/easier to find/etc.

Comment 17

17 years ago
we might, actually. though in nsCOMArray's case, there is no member variable
that depends on T, the only member variable is a nsVoidArray.
Can someone give me a simple non Mozilla testcase for this?

Was this something that became allowed in later C++ standards?

And yes our compiler does suck. But there is not much I can do about it.

If what we are seeing is a genuine bug, I can still try to get it fixed.

We are looking into other compilers, but are stuck with this one for now.

Comment 19

17 years ago
Created attachment 102201 [details]

I *believe* this is a minimized testcase that will fail.  The essential deal
is, class A { TemplatizedClass<B> b; }; declaration should work until such time
as the constructor / destructor actually have to be called.  I guess the OS/2
compiler is compiling these things early.  I'm a little surprised so many
compilers do this, in fact :)

mkaply, can you give this one a try?

And yes, OS/2 is the only build that failed to compile ...
Here is the statement from our compiler folks:

According to the development this works as designed. The development have
returned this defect claim with explanation that IBM C++ compilers 3.6 used a
template instantiation method where all member functions of the class were
always instantiated. Unlike the newer, ISO-14882 compliant compilers, the 3.6
compiler doesn't use the rule of only instantiating the referenced member functions.

So, if we go this way, the OS/2 port of Mozilla will break until we can switch
to a new compiler - we have no timeframe for this.
Well, since the ibm compiler appears to have been EOL'd for OS2, would it be
reasonable to assume that any solution would involve using an entirely different
compiler? (timeless mentioned openwatcom)
Yes, right now we are looking at OpenWatcom. We have no timeframe though.
I got timeless to test, and his version of openwatcom (Watcom C16 Optimizing
Compiler  Version 11.0c) doesn't handle this test case. It also doesn't seem to
know about the true/false boolean types. Its possible that anextra option of
some sort was needed, though - it was a really quick test. OTOH, a quick browse
through the docs at http://www.openwatcom.org/support/reference_content.html
shows functions called |isEmpty| with an int return type, which isn't very hopeful.

gcc doesn't work on os2, either, although there are patches for pgcc for 2.95.3.
pgcc was gcc + 'pentium specific optimisations'. That was released in Jan 2000,
and seems to be unmaintained. theres also a 2.8.1 binary downloadable.


Comment 24

17 years ago
gcc 2.95 compiles Mozilla, what's wrong with that?  Unless the patch sucks,
maybe that will work better than VisualAge :)  timeless, you have a copy of that
We're looking at bring the OS/2 GCC build back. It's just a matter of time.

Comment 26

17 years ago
That would be great :)

Comment 27

17 years ago
collecting under the |nsCOMPtr| tracking bug # 178174
Blocks: 178174
Summary: cannot forward declare nsCOMPtr classes → |nsCOMPtr|: is it time to remove the 'don't forward declare T hack'?


17 years ago
Severity: normal → enhancement

Comment 28

16 years ago
Setting dependent on bug 107291, "drop VisualAge on OS/2"
Depends on: 179118

Comment 29

16 years ago
This hack is also present in nsAutoPtr.h

Comment 30

16 years ago
Created attachment 124785 [details] [diff] [review]
nsAutoPtr.h Patch

This patch does the same thing for nsRefPtr and friends.  sicking has given r=
already.  There are no other copies of the hack that I can find in lxr.
Does the AIX compiler have the same bug as the VisualAge compiler?  (The AIX
tinderbox recently disappeared from SeaMonkey-Ports, so be careful...)

Comment 32

16 years ago
We were having networking problems today which is why the Tinderbox went down. 
I am restarting it now.

I will try the testcase in this defect against the AIX VisualAge C++ v6 

Comment 33

16 years ago
We'll have to find out ... I checked in the nsCOMPtr patch last night, so when
the tinderbox cycles we shall see.

Comment 34

16 years ago
Comment on attachment 124785 [details] [diff] [review]
nsAutoPtr.h Patch

I will not check this in until we verify that AIX has cleared, but the VA
people told us before that they had fixed this bug in later versions of the
compiler, so v6 is probably OK.  Nonetheless, I'd like to get r=/sr= now so I
*can* check this in when that is verified.
Attachment #124785 - Flags: superreview?(dbaron)
Attachment #124785 - Flags: review?(bugmail)
Comment on attachment 124785 [details] [diff] [review]
nsAutoPtr.h Patch

you should probably forwarddeclare some user of nsAutoPtr too. There's a bunch
in transformiix which is XP
Attachment #124785 - Flags: review?(bugmail) → review+

Comment 36

16 years ago
Yesterday's xpcom patch built fine on AIX - we didn't have any errors while
building today's daily build. I have appled the patch to nsAutoPtr.h to a build
tree and rebuilt several files which use nsAutoPtr.h (including
extensions/transformiix/source/xslt/*.cpp). I have not rebuilt the entire tree
with the nsAutoPtr.h patch, but everything seems to work fine.


16 years ago
Blocks: 208188

Comment 37

16 years ago
Fix checked in.
Last Resolved: 17 years ago16 years ago
Resolution: --- → FIXED

Comment 38

16 years ago
OK, so there is a problem which we're trying to figure out if we can get around:
on gcc2.9x and below, a class with an automatic destructor and a
forward-declared nsCOMPtr will fail to compile because the destructor is
compiled when declared, not when used.  This showed up in about 15% of the XSLT
changes (bug 208188).

Comment 39

16 years ago
there's a bug about ABI warnings which relates to these automatic destructors,
perhaps the simplest fix for all of the problems is to simply write the empty
automatic destructors.

Comment 40

16 years ago
That would solve it (I presume you mean declaring all destructors in these
classes and then defining them in the .cpp), but if you *don't* follow that rule
you will break gcc2.9x Linux and waste your own time.  So ... is a C++
portability rule enough?  We have other things you can do that break platforms,
but this one *is* preventable.

sicking has a great idea to make COMPtrs not depend on the type when destructing
(reinterpret_cast to nsISupports before calling AddRef / Release).  That would
allow us to keep the hack out of nsCOMPtr.  Unfortunately for nsAutoPtr and
nsRefPtr there is no such recourse; we'd have to rely on a style rule or a
sizeof hack there.

Another thing that could be done is focus the hack so that it only happens when
the RefPtr / AutoPtr is *destructed* and there is no type information ... but
that probably wouldn't work because as we have seen the automatic destructor is
not compiled until and unless it is needed on the other platforms.  I'll give it
a whirl anyway, on the off chance.
The ABI warnings aare because (basically), if you don't declare a destructor,
the compiler has to place a default one somewhere in the vtable. The spec says
to put it at the end; instead it puts it at the beginning. At some point gc will
move to follow the spec, and that will change the ABI.

See teh ABI bug for more.
You need to log in before you can comment on or make changes to this bug.