Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Directly using Unchecked_Deallocation is frowned upon...

This is true. I admit that I didn't really acknowledge this in the article. I personally don't really like the Ada community's consensus on this matter. In many applications 'let memory leak and let the OS sort it out' just won't cut it. It's true that you can use controlled types for everything, but isn't this just moving the Unchecked_Deallocation somewhere out of sight? Also, if I'd have written 'You can't leak memory in Ada if you stick to using collections', wouldn't that just be like saying 'You can't leak memory in C++ if you stick to using the STL'? The point of the article was to show what Ada and Rust do to outrightly prevent you from shooting yourself in the foot, at the core language level.

There's a lot of misconceptions floating around the Ada community about memory being freed automatically when it goes out of scope, which I think have stemmed from the ARM leaving open the possibility for a compiler to implement its own GC. Admittedly even I was misinformed. In my defence, nearly all the Ada I write is for bare metal, and never touches the heap at all.



> ...'let memory leak and let the OS sort it out'..

I wouldn't be surprise to hear this from C or C++ folks, never heard this in Ada circles, there is always that missile meme going around, and I happened in the past to occasionally drop into FOSDEM Ada's rooms.

Speaking of which,

"Memory Management with Ada 2012 from FOSDEM 2016"

https://archive.fosdem.org/2016/schedule/event/ada_memory/

> Also, if I'd have written 'You can't leak memory in Ada if you stick to using collections', wouldn't that just be like saying 'You can't leak memory in C++ if you stick to using the STL'? The point of the article was to show what Ada and Rust do to outrightly prevent you from shooting yourself in the foot, at the core language level.

A programming language is seldom used without its standard library, I don't care what a plain grammar + related semantics check offer, if there is nothing on the standard library, IDE tooling, libraries to chose from.

Otherwise than you should also do a comparisasion using no_std against Ravenscar profile.

And yes, unless you are using a C++ compiler that offers the option to harden its standard library, you are going to some surprises, starting by having to use at() instead of operator[]() for bounds checking, and even with hardened one, stuff like use-after-free/move only when using a good IDE like VC++/Clion or static/dynamic analysis tooling.


> ...never heard this in Ada circles...

I tried to track down where I read someone advocate this, but I can't find it now. I probably shouldn't have accused the whole Ada community (of which I'm a member) of this attitude. Regardless, I find it odd that 'Unchecked_Deallocation' is so thoroughly discouraged without what I'd consider an acceptable alternative.

> A programming language is seldom used without its standard library...

Nearly all of the Ada I write is for RISC-V microcontrollers, using the 'light' runtime that comes bundled with GNAT. There's no collection classes, and no heap for them to allocate anything in. The semantics of the language are absolutely still important. I still want a language that makes harmful mistakes difficult.


You can even "leak" memory in java if you keep references to objects you don't need anymore xD

Also what is the point of .at()?

try {

    myarray.at(invalid_index);
} catch(std::exeception& e){

    // how do you handle a logic error in your code?
    // does that even make sense philosophically?
}

Yet you could also enable bounds checking for debugging on operator [] or use address sanitizer.


> how do you handle a logic error in your code? does that even make sense philosophically?

In some contexts sure, there's not really much you can do, but in many others it's perfectly clear. In a request-oriented system like a web server, you stop the failed request-handling logic and send back an error code. Exceptions can make this quite natural to implement. Much better than letting the error go undetected, invoking undefined behaviour, and risking mishandling of future requests, or perhaps even a serious security vulnerability.

> Yet you could also enable bounds checking for debugging on operator [] or use address sanitizer.

I'd flip that around. Why bother with additional platform-specific cleverness when the standard library already gives you what you're after?


Nitpick: the index could come from program input. For example:

- if one were to write ‘ed’ in C++, that could be the code that handles going to the n-th line.

- in a lzw decompressor, it could be an integer read from the to-be-decompressed data stream.

In both cases, using at rather than doing a range check first can be defended because failing the range check is an exceptional case.


Contrived examples like that can be done in any programming language.


Every now and then you get comments like this, that are intentionally offensive, like a burning bag of poop.

The point of .at() is to check the bounds at runtime. Here is your answer.

Regarding the comments. You don't necessarily know if it is a logic error and you certainly don't know if it is in your code.

Now onto the how. You handle it like any error. If you don't have a specific error handling strategy, you handle the error at a higher level e.g. your HTTP server returns a 500 http status code and logs the error and the location, so that the developer can fix the bug.

As to whether it makes sense philosophically. The only limitation is your lack of imagination. In C, the program would keep executing and create a security problem. The fact that the exception handler got called in the first place implies that at least the security vulnerability has been averted, meaning that you did indeed recover from the error, even if the catch block is completely empty.


Usually it is a logic error, because you can check the index before.

You could argue it is ok when you use exceptions for control flow (e.g. what people sometimes do in python), but even there it looks questionable imo.


> you can check the index before

You can check manually, but we know programmers can't be trusted to do so correctly every time. There's an ocean of security vulnerabilities because of this, as out-of-bounds access of a raw array is undefined behaviour in C and C++.

It makes good sense to use at in debug builds especially, where you're less concerned about the performance penalty.

In C++ you can define a macro to select between at and [], and while this isn't exactly pretty, it does work:

    #ifdef DISABLE_RANGE_CHECKS
        #define AT_METHOD operator[]
    #else
        #define AT_METHOD at
    #endif
    
    #include <vector>
    
    // ...
    
        i = my_vector.AT_METHOD(my_idx);
> even there it looks questionable imo

Why? Its behaviour is pretty much strictly better than that of raw []. The only downside is a possible performance hit.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: