back to article Rust 1.6 released, complete with a stabilised libcore

The latest release of Rust, the secure systems programming language which will hopefully do away with buffer overflows, features a stabilised core library which should encourage developers' confidence in adopting it – at least for some smaller projects at the time being.. Rust (README) was originally developed by Graydon Hoare …

  1. Mage Silver badge

    People are in Denial about C and C++

    Yet this problem was well known in late 1970s. Languages, tools and frameworks to avoid it were ignored, especially by the PC programming community 1980s.

    I hope this good idea fares better than previous ones. Problem is pressure to start producing code and belief that something so flexible it's insecure is somehow a "better" solution.

    1. Tom 7

      Re: People are in Denial about C and C++

      Don't worry - someone will work out a way to do buffer overflow in rust and it will become commonplace.

    2. Dan 55 Silver badge

      Re: People are in Denial about C and C++

      If you use stl strings/arrays/etc, instantiate objects/structures with new/delete, and use RAII (a C++ invention, no less, but copied by Rust), it's quite difficult to get a buffer overflow or memory leaks in C++.

      1. jzl

        Re: People are in Denial about C and C++

        On one level, you're right. It's hard to get buffer overruns if you use the correct trchniques in C++. But it's easy to use the wrong techniques, as evidenced by the enormous number of overruns in even modern software.

        C and C++ need to be put out to pasture.

      2. DrXym

        Re: People are in Denial about C and C++

        "it's quite difficult to get a buffer overflow or memory leaks in C++."

        It's not hard to get memory leaks - just allocate things and forget to clean them up, or put convoluted ownership rules into the API. Things like shared / scoped points can help a lot, but shared pointers aren't a panacea and come with their own issues, e.g. sometimes objects have to be cleaned in a specific way rather than by the last reference.

        Buffer overflows too. I had a buffer overflow occur in a piece of code which was setting a tooltip on a Windows app. The code did a strcpy into the struct without checking the length. Later, when the application was shutting down it would crash because the heap was corrupted. It took days to track down that damned bug. The problem here is that yes C++ has safer classes but it never bothers to deprecate the unsafe ones. It's also quite common for libraries to use their own abstractions so you can't just pass around STL classes.

        So to me, a language which has protection built in from the bottom up is a bonus. Every compile error is a potential bug averted at runtime. My biggest fear for rust is that nobody is going to port code from C++ (they might wrap some up, but not port it) so it will have to build up a large body of useful functionality on its own and quickly. I wonder if Rust's future is actually in places that might traditionally use something like Ada.

  2. choleric

    Rhyme or reason?

    There must be a good story about the name for this project, or else it's a rather unfortunate choice for something they are hoping with spread onto heavy iron around the world.

    1. Not That Andrew

      Re: Rhyme or reason?

      IIRC it's named after "Rust Never Sleeps", the Neil Young album named after the slogan of Rustoleum, an anti-rust paint, although Wackypedia claims it's named after the fungal infection that affects plants.

  3. Triboolean
    Pint

    I took a very quick look at rust docs. Saw this line:

    let x = 5;

    Whenever I see "let", I think ANSI Minimal BASIC from 1980.

    Am I wrong to make this association?

    1. Reginald Marshall

      I took a very quick look at rust docs. Saw this line:

      let x = 5;

      Whenever I see "let", I think ANSI Minimal BASIC from 1980.

      Am I wrong to make this association?

      In this case, you are. If you're familiar with C#, think var (Rust's let is a bit more complicated than that, but it does introduce a local variable binding whose type is inferred by the compiler.)

    2. Bronek Kozicki

      IIRC modern C++ equivalent to above Rust is

      const auto x = 5;

      I recon "C/C++ programmers" i.e. kind of people who are still confused about which is C and which is C++ are also confused about the above, more modern, C++.

      1. This post has been deleted by its author

        1. Dan 55 Silver badge
          Holmes

          It knows the min and max values of signed int and unsigned int and it knows the types of other variables that may assign values to this one or read values from this one... Elementary...

          1. Fibbles

            Thought about it for a minute or two so I deleted the post, somehow you've still replied.

            A literal integer is going to be interpreted as signed unless you specifically say otherwise.

            i.e.

            const auto x = 5u;

            1. Dan 55 Silver badge

              Sorry, not my finest post. After reading up on it auto is indeed less clever than I thought, if it sees an int you get an int.

              It's supposed help mainly with templates and iterators. It does dereference though (another post), if you give it a reference to something it strips the reference and you just get a variable of type something.

              1. Fibbles

                Auto is supposed to be used to save time when the type is already known which was part of my problem with the example originally. It's not supposed to introduce ambiguity which is what would happen if a literal could change from signed to unsigned simply based on its value. The programmer might expect an overflow into the negative but the compiler chooses to make the const variable unsigned and so it remains positive. It comes back to one if the core tenets of C and C++, that the compiler does what you tell it rather than what it thinks you probably meant.

                You forgot return types BTW. It's one if my favourite things about auto.

                Old way:

                std::vector<std::tuple<int, std::string, double>>& foo = bar.get_stupid_container_ref();

                New way:

                auto& foo = bar.get_stupid_container_ref();

    3. DrXym

      Javascript has acquired a "let" keyword too and for hilariously awful reasons.

      When you declare a var in JS scope is only global or to the enclosing function - you can declare a var in a block and reference it outside of that block!.

      {

      var x = 3

      ///... rest of scope

      }

      console.log("x = " + x);

      This is nonsensical but completely legal and outputs "x = 3". The reason is that JS "hoists" the decl to the global or function scope level. Rather than fix this insane behaviour, ECMAScript 6 is introducing a let keyword where a var can have proper local scope.

      1. Michael Wojcik Silver badge

        Rather than fix this insane behaviour

        For the usual reason: fixing it would break far too much extant code.

        At least the ECMAScript committee acknowledges issues like the language's feeble scoping and is working on extensions to address them.

    4. Michael Wojcik Silver badge

      Whenever I see "let", I think ANSI Minimal BASIC from 1980.

      Am I wrong to make this association?

      LISPers might say so.

      BASIC got the LET keyword from LISP, which AFAIK was the first programming language to use it. The usage was adopted from the mathematical convention, presumably.

    5. herman

      "let x = 5' makes me think of Bash.

  4. daajjall

    As a Brit, I'm miffed the ARM platform is still broken and nobody seems to bloody care! Definitely not a serious language contender on the best hardware platform at the moment.

    You children are overly enthusiastic, methinks - C++ doesn't stand still and C++17 will make Rust a much less attractive option.

    1. Blank Reg

      Every iteration of C++ makes it a less attractive option. It has become a horrible mess as they continue to tack in more language features. The syntax is just atrocious now and I don't see how they fix it without starting over.

      1. Anonymous Coward
        Anonymous Coward

        The thing is, most of the C++11/C++14 additions have simplified syntax.

        Compare idomatic loops in C++ 03;

        #include<vector>

        #include <iostream>

        std::vector<int> numbers(0,10);

        std::vector<int>::const_iterator begin(numbers.begin());

        for(std::vector<int>::const_iterator end(numbers.end()); begin != end; ++begin){

        std::cout << " a number " << *begin << "\n";

        }

        Compare idomatic loops in C++ 11;

        #include<vector>

        #include <iostream>

        std::vector<int> numbers(0,10);

        for(const auto & v: numbers){

        std::cout << " a number " << v << "\n";

        }

        1. phil dude
          Thumb Up

          thanks...

          @sed_gawk thanks for the prod, I'll read up. I recently prodded my co-author to embrace C++11 for our codes, as it has become part of the GCC collection, and therefore deployable on many platforms.

          For the supercomputers I am looking at OpenACC etc... to try and let the compiler to the hard memory management work...

          P.

          1. Anonymous Coward
            Anonymous Coward

            Re: thanks...

            @phil_dude, There's a better example if you do a lot of concurrent stuff..

            C++11 subtly changed the definition of const. So const now for all intents means "thread safe".

            A very useful change, the threading stuff is nice too - https://gist.github.com/jamal-fuma/eb3f46fd2da666bcf7c3 has a toy parallel dot product.

            1. Anonymous Coward
              Anonymous Coward

              Re: thanks...

              @phill_dude - the cliff notes version is..

              1) almost always auto - for scalars and values returned from functions;

              2) replace new T() by std::make_shared<T>() or std::make_unique() (if you can go C++14)

              3) prefer move only types, you can put then in STL containers like vector<unique_ptr<T>>

              4) 'typedef' is now spelt using so not 'typedef int foo_bar_t;' but 'using foo_bar_t = int;' the old way still works but the new way is preferred in new code.

              5) default/delete so instead of writing exactly what the compiler generated for a default constructor by hand, you do 'struct Thing{ Thing() = default; };' and for non copyable thing you do 'struct Thing{ Thing(const Thing &) = delete; }';

              6) Final is quite handly, so you can seal virtual hierarchy i.e. it's a compiler error to try and override this function in a derived class.

              Atomics/threads and futures are all quite nice but the above cut down quite a bit on our source base, and meant a lot of stuff which required boost is now available as part of the platform.

              1. James Hughes 1

                Re: thanks...

                I'm with sed gawk. Moved to C++11, much easier to get on with, and with loads of the boost:: stuff now in std:: makes it much handier.

        2. James 47

          Won't const auto& give you a reference to the members of the array instead of their actual values? Why would you want the extra memory dereference?

          1. Anonymous Coward
            Anonymous Coward

            for(const auto & v: numbers) ..

            For a vector the iterator is likely (but not required) to be a pointer, so there is a single memory dereference in both the C++03 and the C++11 version, i.e. they should generate identical code.

            The 'const auto &' here is saying don't copy the values, you get an implicit deference (hence v, and not *v), so what you are capturing by const reference is actually the member value

            but the item being deferenced is an iterator rather than the member reference.

            The main difference is that the dereference in the C++03 version is explicit '*begin' and the C++11 version is implicit 'v', oh and the C++11 version will also work with a plain array e.g.

            int numbers[10] = {0};

            for( const auto & v : numbers){ ... } // works just fine.

            They also work on user defined types provided you expose either begin() and end() member functions or overload std::begin()/std::end() for your type.

  5. a_yank_lurker

    Legacy code

    The biggest hurdle Rust, Go, and Julia face is the amount of legacy code written in C, C++, and Fortran still use and will be use for a long time still.

  6. phil dude
    Coat

    interesting, but...

    I had a quick read, and like most new languages, it has the essential starting features and lacks the precision of the existing languages. I am *not* saying the mountain of C/C++/Fortran code is some how preferred, but the same thing that makes it difficult to make "safe", also enables it to run efficiently.

    And the reason is simple - control of the memory hierarchy.

    My physics codes use vectors, because vectors can be made cache efficient. I noticed Rust has spawn'ing built in, but I wonder if that is sufficient? There's explicit parallelism as well (send/recv), and "safe shared mutable state". I think that's the Fortran COMMON block, no?

    So we'll see. Another language to give the undergrads a fright. If they added features for memory pinning (which of course needs pointers), I might be interested.

    And we haven't even talked about GPU offloading yet...OpenACC/OpenMP is with us!!

    P.

    1. Francis Vaughan

      Re: interesting, but...

      Pointers are not the problem. It is any language that allows pointers to be manufactured or modified directly by user code that is the problem. Languages where you write your own loop control and indexing are part of this. That is where the buffer overflows, stack smashing, and a large number of other amusing problems come from.

      Any language where type casting is allowed, or languages, that support pointer arithmetic are intrinsically insecure. It matters not that C++ has some nicer abstractions available. You can still write utterly insecure code in it. Until the language prohibits insecure code its security is only a matter of coding with a set of rules next to you. And you can do that in assembler. C++ remains syntactic sugar over the top of C for any questions of security. Unless the language stops you writing insecure code, it does not support security intrinsically.

      If you want high performance numeric code you want a language that allows you to specify the mathematics of what you are doing properly, and then allows you to identify the parts where there are issues worth addressing (preferably with pragma like hints.) Modern Fortrans are actually pretty good at this. They still allow insecure code to be written, but it would not be a huge stretch to modify them to remove most of the old insecure legacy bits. Coding with forall and where clauses can capture the mathematics better, allow for better optimisation, and does not require indexes and pointers to be exposed.

      1. Anonymous Coward
        Anonymous Coward

        Re: interesting, but...

        This is just not true.

        The difference between secure code and insecure code is testing and auditing, combined with people who understand the tools.

        Secure code is not just code that doesn't crash, in a lot of ways a nice segv is a lot better than exposing the information your code was intended to "secure".

        It's possible to make any code secure if you have enough time and money to throw at it, once you define security properly, it seems to be largely independent of language/operating system.

        1. Francis Vaughan

          Re: interesting, but...

          If you have enough time and money - sure.

          But we don't.

          If we had some bacon we could have some bacon and eggs - if we had some eggs.

          We don't have the time, the money, or the required number of skilled people. Nor will we ever. It is the nature of the world. So it simply isn't a solution by itself.

          So you need better tools. Researching better tools is probably a good idea. Researching better tools seems to have provided some useful benefits in the past. It might be a good policy to stay on it. Rust may not be the answer, but C++ most assuredly isn't, as is demanding impossible funding and time.

          1. Anonymous Coward
            Anonymous Coward

            Re: interesting, but...

            C and C++ are known quantities with foibles that are correctable with small amounts of assembly.

            We have attractively priced binary instrumentation tools such as valgrind.

            We have reassuringly expensive static analysis tools such as coverity.

            Clang will tell what line you made a mistake on.

            It's often cheaper to hire people who know how to use the tools than to clean up the mess.

          2. Dan 55 Silver badge

            Re: interesting, but...

            You're looking at the wrong language. If you want to make it impossible to do things then Java is that way...

            Otherwise a lint highlighting coding techniques which are frowned upon for ordinary use but may be acceptable in certain circumstances is what you want.

          3. Anonymous Coward
            Anonymous Coward

            Re: interesting, but...

            If you don't have the time and money to secure your code, your code will be insecure by design.

            Hence your language of choice doesn't matter.

        2. a_yank_lurker

          Re: interesting, but...

          @sed gawk - Testing will not capture all the errors, only some. Coding standards, etc only mitigate against insecurity. The security goals of the newer languages of Rust, Julia, and Go are build it into the compiler and language design and thus not rely on the programmer to be perfect. The primary security criticism of C and C++ is that they require the programmers to execute certain activities perfectly which is virtually impossible on any large code base. Thus C/C++ is prone to certain amount of bugginess because of the underlying. design.

          Whether they are as successful as they hope, time will tell. But their designers are correct - the best time to address certain types of security problems is in the fundamental design of the language. Older languages suffer from the problem of having to maintain a degree of backwards compatibility with the code bases. An inherent problem and some insolvable problem.

          1. Anonymous Coward
            Anonymous Coward

            Re: interesting, but...

            Testing won't capture all the bugs, but testing, auditing, and all the other tools of the trade will get you into the right ballpark, eventually you'll get enough of bugs squashed that you can ship it. Sometimes that's good enough, sometimes not, projects fail!.

            You cannot fundamentally ignore the machine the code runs on, and hand wave it with compiler and language design. The author of the code is responsible for expressing intent with clarity.

            When the intent is not clear, the code will do the wrong thing, in any language.

            One cannot design tools to make people think clearly, hence it's easier to ignore all of that, and focus on what the code is *doing* to the machine when trying to figure out what it's doing (the reason someone initially invested the development effort). C makes it easy, C++ makes it possible, Go - not so much.

            Rust seems to have dodged the Go/Java bullet i.e. making calling C/C++ code really slow.

            C++ is doomed to succeed, it's functional enough, concurrent enough, portable enough, and *standard* enough.

            There just isn't any point in jumping onto golang or rust or whatever, write in C++ if you can, C if you must, and ASM only in dire need.

            Everything else is mostly acceptable for some scripting language, I still use a lot of shell but ruby is nice.

      2. TeeCee Gold badge

        Re: interesting, but...

        I'd go a step further. Any language where you get to play around with memory directly, rather than just declaring variables and letting the compiler do the bit that humans invariably fuck up at some point, is totally unsuitable as an application development tool.

        That sort of language is for bare metal shit only.

  7. cmannett85

    I wish people will stop lumping C and C++ together. C by default is very low level and easily dangerous to use, where as modern C++ with it's dynamic memory management and containers is completely different.

    1. Francis Vaughan

      Last I saw C++ did not support garbage collection (they pulled it from the spec.) Dynamic memory management is not the same as automatic memory management. C++ still provides all the tools you need to utterly subvert the memory abstractions - especially when you start calling libraries that were not written with the same abstractions. You both can and must be able to find and manufacture naked pointers and use them. Once the language allows this you are dead.

      1. Anonymous Coward
        Anonymous Coward

        No it's not garbage collection but it amounts to automatic resource management

        Unless you are trying to solve the A-B-A problem, Garbage collection rather than automatic resource management is less useful in C++.

        What is it about pointers that upsets people? Is an ArrayIndexOutOfBoundsBecauseYouCantCountExceptionalException really preferable to sigsegv ?

        The C++ conventions are simple. 1) don't allocate memory for buffers, use a contiguous sequence container instead. (vector in C++ 03, vector and std::string in C++11/14).

        Allocation/Deallocation/Resizing are handled for you, so you don't need GC.

        struct Think {};

        // Idiomatically, on the stack so no alloc/hence no free/hence no need for GC

        Thing thing;

        ...

        In C++11 it's trivial to grab a chunk of memory and make it impossible to leak.

        { // if you really must allocate this on the free store

        std::unique_ptr<Thing> pthing{}; // allocates memory which I cannot leak.

        ...

        // what ever happens here pthing will be cleaned up/.

        }

        // pthing has been released

        1. Francis Vaughan

          Re: No it's not garbage collection but it amounts to automatic resource management

          A segv is when you are lucky, and the access went somewhere protected. Program crashes right there and you get some clue as to why. A buffer overrun is when you run into the next variable allocated in memory and no protection violation is caught. Your program doesn't crash, behaves badly (anything up to your system being pwned) and you never know.

          An indexing exception is what you expect from any sensible language. A segv tells you that the language or its implementation has a bug. Any language that allows you to generate a segv is insecure. It is all well and good to have the nice new abstractions. But why then does the language retain the insecure ones? If they are bad practice, remove them.

          1. Anonymous Coward
            Anonymous Coward

            Re: No it's not garbage collection but it amounts to automatic resource management

            "An indexing exception is what you expect from any sensible language."

            Agreed so having followed rule 1), you'd use std::vector::at() which throws an std::out_of_range exception.

            http://en.cppreference.com/w/cpp/container/vector/at

            "A segv tells you that the language or its implementation has a bug."

            No, a segv says "I don't know that address mapping", it's quite useful when

            doing things like paging virtual memory, see for a handy list of what it's purpose is, https://www.gnu.org/software/libsigsegv/.

            C++ simply demands you use it deliberately and carefully, why is that such anathema?

            The customer cares if he turns the handle and widgets pop out, that's it.

            Languages which work everywhere, have sane portable datastructure libraries, and *known* problems,

            are preferred over trying to m'arcitect a way of ignoring Sturgeon's law.

            https://en.wikipedia.org/wiki/Sturgeon's_law law

        2. GrumpenKraut
          Thumb Up

          Re: No it's not garbage collection but it amounts to automatic resource management

          > ArrayIndexOutOfBoundsBecauseYouCantCountExceptionalException

          Lovely, I'll use that in the future!

      2. Dan 55 Silver badge

        You don't need garbage collection with RAII and scoped objects.

  8. Anonymous Coward
    Anonymous Coward

    I can't help but feel it could be cleaner...

    Maybe this is a fault of the manual rather than the language but the Dining Philosophers example spends an awful lot of time talking about strings rather than dining philosophers.

    Things like that, plus a general sense of deja vu (it looks a bit like C with *var and &var but isn't) just leaves me feeling slightly uneasy. Given the opportunity to start completely afresh, I'm wondering why things like &var persist in the syntax?

    This isn't to say it's bad. Nor does it mean that anything else is better. Just that it could be better still.

  9. John Smith 19 Gold badge
    Unhappy

    IDK. Maybe tools that show programmers why there cherished code idion is dumbass?

    So they might change it.

    Or at least know when they are being a dumbass?

    1. Anonymous Coward
      Anonymous Coward

      Re: IDK. Maybe tools that show programmers why there cherished code idion is dumbass?

      Actually this sort of thing exists in Clang, it will say this is a better ways to do it, and can in some cases rewrite the source code for you. Google have a nice demo of this. I'll paste it if I come across the link

      1. John Smith 19 Gold badge

        Re: IDK. Maybe tools that show programmers why there cherished code idion is dumbass?

        "Actually this sort of thing exists in Clang, it will say this is a better ways to do it, and can in some cases rewrite the source code for you. "

        My point was that while making it easier to write the next generation of code is good most of the grief is being caused by problems in existing code, which really needs some tools to run over it to find (and maybe fix) issues.

        We've seen issues with code that's been open source for twenty years and no one spotted a bug which was likely found by the NSA sometime in the mid 90's.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Other stories you might like