C++: Today I Learned How to Use dtor Order to Detect Temporaries

On Friday I wrote the kind of C++ bug you usually write on Fridays: a stupid one. I was trying to create an object that would live exactly until the end of the block using RAII (as you do). This is how I wrote it:

RAII(parameters);

What I should have written was:

RAII someRAII(parameters);

Because, according to 12.2/3 of the ISO C++ standard, the temporary object created by the RAII construction in the first case will only last until the end of its containing expression.Whereas in the second case the temporary is assigned a reference `someRAII` and its lifetime is thus lengthened to the lifetime of the reference.

As I had it written, the RAII would last until the semicolon. Which isn’t very long at all for something I was supposed to be using to mark a stack frame’s duration.

There should be a law against this! I thought. Why does the compiler even have that lever?

Or, more seriously, how can I stop this from happening to me again? Or to others?

This being Gecko I’m hacking on, :froydnj informed me that, indeed, there are two different ways of catching this blunder. Both happen to be documented on the same page of the MDN about how to use RAII classes in Mozilla.

The first way is adding custom type annotations to mark the class as non-temporary, then having a clang plugin throw during static analysis if any scope has a “non-temporary”-marked class being allocated as a temporary.

(( #include “mfbt/Annotations.h” and add MOZ_RAII to your class decl to use it.))

That only works if you’re on a platform that supports clang and have static analysis turned on. This wouldn’t help me, as I’m developing Gecko on Windows (Why? A post for another time).

This brings us to the second, cross-platform way which is unfortunately only a runtime error. As a runtime error it incurs a runtime cost in CPU and memory (so it’s only compiled on debug builds) and it requires that the code actually run for the test to fail (which means you might still miss it).

This second way is a triplet of macros that annotates an RAII class to have the superpower to detect, at runtime, whether or not an instance of that class being destructed was allocated as a temporary or not.

Sound like magic? It all comes down to what order destructors are called. Take two classes, A and B such that A’s ctor takes a temporary B as a default arg:

A(B b = B())

Try allocating an instance of A on the stack and watch what order the ctors/dtors are called:

A a;
B()
A()
~B()
~A()

Allocate an A as a temporary and you get something different:

A();
B()
A()
~A()
~B()

(Here’s a full example at ideone.com so you can run and tweak it yourself)

They both start the same: you need to create a B instance to create an A instance, so b’s ctor goes first, then a’s.

b is a temporary, so what happens next is up to section 12.2 of the standard again. It lasts until the semicolon of the call to the A ctor. So in the stack case, we hit the semicolon first (~B()) then the stack frame holding a is popped (~A()).

When a is also a temporary, it gets interesting. Who goes first when there are two temporaries that need to be destructed at the same semicolon? Back to 12.2, this time to footnote 8 where it says that we go in reverse order of construction. So, since we call B() then A(), when we hit the semicolon we roll it back as ~A() then ~B().

So if ~A() happens before ~B(), then you were a temporary. If not, you weren’t. If you tell A when B is destructed, when A goes away it’ll know if it had been allocated as a temporary or not.

And, of course, this is exactly how those macros grant superpowers:

  1. MOZ_GUARD_OBJECT_PARAM puts the temporary B b = B() in your “A” class’ ctor args,
  2. MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER puts a little storage on your “A” for B to use to notify your “A” when it’s been destructed.
  3. MOZ_GUARD_OBJECT_INIT tells B how to find your “A”

(( It’s all in GuardObjects.h ))

It takes what is a gotcha moment (wait, the destruction order is different when you allocate as a temporary?!) and turns it into a runtime test.

Ah, C++.

:chutten

Advertisements

How Mozilla Pays Me

When I told people I was leaving BlackBerry and going to work for Mozilla, the first question was often “Who?”

(“The Firefox people, ${familyMember}” “Oh, well why didn’t you say so”)

More often the first question (and almost always the second question for ${familyMember}) was “How do they make their money?”

When I was working for BlackBerry, it seemed fairly obvious: BlackBerry made its money selling BlackBerry devices. (Though obvious, this was actually incorrect, as the firm made its money more through services and servers than devices. But that’s another story.)

With Mozilla, there’s no clear thing that people’s minds can latch onto. There’s no doodad being sold for dollarbucks, there’s no subscriber fee, there’s no “professional edition” upsell…

Well, today the Mozilla Foundation released its State of Mozilla report including financials for calendar 2014. This ought to clear things up, right? Well…

The most relevant part of this would be page 6 of the audited financial statement which shows that, roughly speaking, Mozilla makes its money thusly (top three listed):

  • $323M – Royalties
  • $4.2M – Contributions (from fundraising efforts)
  • $1M – Interest and Dividends (from investments)

Where this gets cloudy is that “Royalties” line. The Mozilla Foundation is only allowed to accrue certain kinds of income since it is a non-profit.

Which is why I’m not employed by the Foundation but by Mozilla Corporation, the wholly-owned subsidiary of the Mozilla Foundation. MoCo is a taxable entity responsible for software development and stuff. As such, it can earn and spend like any other privately-held concern. It sends dollars back up the chain via that “Royalties” line because it needs to pay to license wordmarks, trademarks, and other intellectual property from the Foundation. It isn’t the only contributor to that line, I think, as I expect sales of plushie Firefoxen and tickets to MozFest factor in somehow.

So, in conclusion, rest assured, ${conceredPerson}: Mozilla Foundation has plenty of money coming in to pay my…

Well, yes, I did just say I was employed by Mozilla Corporation. So?

What do you mean where does the Corporation get its money?

Fine, fine, I was just going to gloss over this part and sway you with those big numbers and how MoCo and MoFo sound pretty similar… but I guess you’re too cunning for that.

Mozilla Corporation is not a publicly-traded corporation, so there are no public documents I can point you to for answers to that question. However, there was a semi-public statement back in 2006 that confirmed that the Corporation was earning within an order of magnitude of $76M in search-related partnership revenue.

It’s been nine years since then. The Internet has changed a lot since the year Google bought YouTube and MySpace was the primary social network of note. And our way of experiencing it has changed from sitting at a desk to having it in our pockets. Firefox has been downloaded over 100 million times on Android and topped some of the iTunes App Store charts after being released twelve days ago for iOS. If this sort of partnership is still active, and is somewhat proportional to Firefox’s reach, then it might just be a different number than “within an order of magnitude of $76M.”

So, ${concernedPerson}, I’m afraid there just isn’t any more information I can give you. Mozilla does its business, and seems to be doing it well. As such, it collects revenue which it has to filter through various taxes and regulation authorities at various levels which are completely opaque even when they’re transparent. From that, I collect a paycheque.

At the very least, take heart from the Contributions line. That money comes from people who like that Mozilla does good things for the Internet. So as long as we’re doing good things (and we have no plans to stop), there is a deep and growing level of support that should keep me from asking for money.

Though, now that you mention it

:chutten