Live data from Hacker News

Show HN: Modifying Clang for a Safer, More Explicit C++

github.com

1–10 of 91 posts

Show HN: Modifying Clang for a Safer, More Explicit C++

#1
Modified C++

Inspired by the paper "Some Were Meant for C" by Stephen Kell, I decided to show that it's possible to iterate C++ to be safer, more explicit, and less error-prone.

Here's a possible starting point: I didn't invent a new language or compiler, but took the world's best compiler, clang, and modified it to begin iterating towards a new furture of C++. Naming things is hard, so I call this 'Modified C++'. Some of the following could be implemented as tooling in a linter or checker, but the idea is to update the compiler directly. I also wanted to learn more about clang. This compiler needs a flag to enable/disable this functionality so that existing library code can be used with a 'diagnostic ignored' pragma.

You can build clang using the normal non-bootstrap process and you'll be left with a clang that compiles C++ but with the following modifications:

     - All basic types (excluding pointers and references) are const by
     default and may be marked 'mutable' to allow them to be changed after
     declaration
     - Lambda capture lists must be explicit (no [&] or [=], by themselves)
     - Braces are required for conditional statements, case and default
     statements within switches, and loops
     - Implicit conversions to bool are prohibited (e.g., pointers must be
     compared against nullptr/NULL)
     - No goto support
     - Explicit 'rule of six' for classes must be programmer-implemented
     (default, copy, and move c'tors, copy and move assignment, d'tor)
     - No C style casts

Here's an example program that's valid in Modified C++:

    mutable int main(int, char**)
    {
      mutable int x = 0;
      return x;
    }


    Here's another that will fail to compile:


    mutable int main(int, char**)
    {
      int x = 1;
      x = 0;  // x is constant
      return x;
    }

I'd like your feedback. Future changes I'm thinking about are:

     - feature flag for modified c++ to enable/disable with 'diagnostic ignored'
     pragma, to support existing headers and libraries
     - support enum classes only
     - constructor declarations are explicit by default
     - namespaces within classes
     - normalize lambda and free function syntax
     - your ideas here

Show HN: Modifying Clang for a Safer, More Explicit C++
github.com

Re: Show HN: Modifying Clang for a Safer, More Explicit C++

#2
How hard would it be to automatically convert some existing C++ into the new language? It seems like your compiler can diagnose the errors, so inserting `mutable` and `bool(...)` should be possible.

It might be interesting to do this on an existing codebase just to see where mutable is needed.

Re: Show HN: Modifying Clang for a Safer, More Explicit C++

#3
> - All basic types (excluding pointers and references) are const by default and may be marked 'mutable' to allow them to be changed after declaration

If you're not changing how const works, then this has limited utility in C++ because C++ const has all sorts of problems (e.g. not transitive). Also, what does the "mutable" annotation for a free function (i.e. main) mean? That just seems weird.

> - Lambda capture lists must be explicit (no [&] or [=], by themselves)

[&] is pretty valuable in cases where you do something like invokeSynchronously([&] {...})

I don't know that your changes will ever see much adoption because it won't be able to compile anything more complex than a "hello world" program as all the things you disallow are used & the porting effort is not cosmetic. Additionally, you're not actually fixing any of the problems people have with C++. So:

1. Consider fixing const semantics if you're going down the path of defining a new language

2. Think about how to fix memory safety and issues around UB which are the #1 sharp edges for C++

I don't know if you're achieving the goal of a safer, less error-prone language with the changes outlined. Have you looked at the things Carbon [1] is doing? I'd say that's an attempt to define a spiritual successor to C++, one that can easily interoperate with C++ but when you stay within the language it's safer.

[1] https://github.com/carbon-language/carbon-lang

Re: Show HN: Modifying Clang for a Safer, More Explicit C++

#5

> - All basic types (excluding pointers and references) are const by default and may be marked 'mutable' to allow them to be changed after declaration If you're not changing how const works, then this has limited utility in C++ because C++ const has all sorts of problems (e.g. not transitive). Also, what does the "mutable" annotation for a free function (i.e. main) mean? That just seems weird. > - Lambda capture list…

Thank you for this great feedback. I'll do my best to respond to each of your points:

WRT const, you're correct and I'd need to go further in updating const behaviors in the language. I stole this idea from Rust (sort of) in that variable declarations in that language are const by default. Essentially, I wanted to 'flip' the semantics in C++ to match, and use mutable to allow variables to change after their declaration. I could go further to enforce transitivity (e.g. so you can't do something like mutable x = y; where y is const).

[&] is handy indeed yet this was motivated by my experience in legacy heavy codebases where there are often many variables in scope and some with external consequences (e.g. file descriptors, sockets). I don't want these accidentally captured if the lambda invocation site has lifetime implications beyond those resources.

I think I'm achieving the goal of a safer, less error-prone language because these changes could've prevented the 2014 'goto fail' from happening (and not just because the keyword goto would be omitted but because there was a conditional without braces in the affected source making the code less explicit and less clear).

Re: Show HN: Modifying Clang for a Safer, More Explicit C++

#6

Apart from the mutable keyword, can't these be implemented as a clang diagnostic plugin? Then it can be used to enforce a stricter style guide. As another commenter pointed, mutable will be probably of limited use anyway.

Yes, some (maybe most) could be implemented in a plugin. I wanted to make these changes in part to better understand the clang internals and also show that rather than use external tooling, the language itself can (should?) be changed.

Re: Show HN: Modifying Clang for a Safer, More Explicit C++

#8
Rather than build a new compiler, I wonder if this might be easier to integrate as a static checker. IMO clang static checks are not that difficult to write. The hardest thing can be the query to find the interesting elements. But you're banning/requiring fairly high-level language elements so they should be pretty easy queries to write.

Re: Show HN: Modifying Clang for a Safer, More Explicit C++

#10
post #9

I think it's a great experiment, keep doing what you're doing. Removing the footguns from C++ without wildly changing the syntax up is a solid idea.

Thanks! Aside from the default const/mutable change, this was my approach. To improve adoption, it would be easy to add a feature flag for this set of changes which could be applied on a per file basis.
Post reply on HN