> > There should be a way to indicate in a switch statement whether you intend
> > to cover all the cases:
> > 
> >    enum A { a, b, c };
> > 
> >    switch (x) {
> >       case a:
> >          return true;
> >       case b:
> >          return false;
> >    }
> > 
> > There needs to be a way to tell the compiler to reject this switch
> > statement because it doesn't cover all the cases. To work around the lack
> > of that feature, we end up writing:
> > 
> >    switch (x) {
> >       case a:
> >          return true;
> >       case b:
> >          return false;
> >       case c:
> >          return false;
> >       default:
> >          PR_NOT_REACHED("unexpected case"); // or...
> >          MOZ_CRASH("unexpected case");
> >    }
> > 
> > But, that's turning a statically-detectable error into a potential runtime
> > crash, unnecessarily. Currently, we can mess with compiler warnings
> > settings to catch these but that isn't good enough.
> 
> I'd very much like to see this as well!
> 
> The C++11 attribute syntax might be a good way to accomplish this without
> inventing new syntax. For example, the standard could define an "exhaustive"
> attribute on a switch statement for an enumeration:
> 
>    enum A { a, b, c };
>    A x;
>    ...
>    switch (x) [[exhaustive]] {
>       case a:
>          return true;
>       case b:
>          return false;
>    }  // error: 'c' is not handled
> 
> I'll find out if something like this has ever been discussed.

I don't believe this has been proposed before, which means it may
very well be worth for us to try.

A couple of minor cautions:

  - C++11-style attributes aren't supposed to change the semantics
    of a program, so a proposal to express this as an attribute
    might not fly. (I find this unfortunate because the grammar
    is full of places where attributes can be placed, so in the
    absence of this artificial limitation on what attributes can
    do, proposals like this could be expressed without further
    changes to the grammar).

  - The committee tends to be generally wary of introducing new
    syntax which expresses a slightly safer or otherwise different
    variant of an existing construct, for various reasons including
    language complexity, teachability, keyword shortage / reluctance
    to add new keywords, and readability (one could imagine proposing
    the syntax "explicit switch", but is it clear what "explicit"
    means? a paper presented in Rapperswil [1] proposed a different
    meaning for that exact syntax!).

That said...

> Assuming that this hasn't been already discussed and passed up for some
> technical reason, it's very much possible that all that is required for
> something like this to be standardized is for someone to write a paper
> proposing it, and someone to present it at a committee meeting. I'd
> gladly do the second task, and help someone with the first.

... this offer still stands.


> > Large parts of the standard library are unusable or nearly unusable when
> > exceptions are disabled, such as the standard containers. Sometimes they
> > can be used if the default allocator is changed to abort on out-of-memory,
> > but often abort-on-OOM is not what you want. Thus, much (most?) Gecko code
> > cannot use a huge part of the standard library. For example, it should be
> > made possible to call std::resize() when exceptions are disabled and
> > without triggering abort-on-OOM, such that the caller can detect when the
> > resize fails. Similarly, it should be possible to attempt to append an
> > element to std::vector without an exception being throw or the process
> > being aborted on failure, but with the error still detectable.
> 
> From what I've heard at committee meetings, the dominant opinion on this
> topic seems to be that, since exceptions are part of the standard language,
> library writers shouldn't have to go out of their way to cater to people
> who don't use them.
> 
> That said, there are some libraries which have an option to use an error
> code instead of an exception for error handling. I'm thinking in particular
> of the Filesystem TS [1].
> 
> I'll try to find out some more concrete information on this topic.

I spoke to several people about this, and this was the general
impression I got:

  - OOM is widely considered to be a condition that one should not
    try to recover from. Even catching std::bad_alloc is generally
    considered to be code smell.

  - Therefore, for standard library functions where the only
    exception that can be thrown (other than exceptions thrown by
    methods of the user's classes, such as T in vector<T>) is 
    std::bad_alloc - like vector::resize() -  the committee is 
    very unlikely to consider an alternative interface which does 
    not throw.

  - For standard library functions that can throw other types of
    exceptions, the committee may be open to such an alternative
    interface. Proposals would be evaluated on a case-by-case basis.

As always, if someone's interested in creating such a proposal,
I'm happy to help.


> > std::shared_ptr is mostly unusable in Gecko code because there's no way to
> > specify whether you need thread-safety or not (usually you don't). There
> > should be a way to specify whether you want to pay the cost of thread
> > safety when using it.
> 
> I would like to see this as well.

I talked to Jonathan Wakely (a libstdc++ maintainer) about this, and
he said that this has been discussed but rejected, for two reasons.
First, it encourages brittle code, where instances that don't need
thread safety at one point in time come to need it as the codebase
evolves. Second, it adds complexity to the library and diminshes its
teachability to have two different flavours of std::shared_ptr.

Note that libstdc++ provides a '__shared_ptr<T, LockingPolicy>' class 
as an extension. We could take advantage of this when using libstdc++
without it becoming standardized, as follows:

namespace mozilla {
  template <typename T, LockingPolicy L>
  #ifdef /* we are using libstdc++ */
  using SharedPtr = __shared_ptr<T, L>;
  #else
  using SharedPtr = std::shared_ptr<T>;
  #endif
}

(and then use mozilla::SharedPtr<T, L> with appropriate values of L
in our code).


Cheers,
Botond

[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3879.pdf
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to