New Safe C++ Proposal

Pages: 1... 3456
If something like pointer arithmetic is done, it can be right or wrong - hence I don't think it should be restricted.
Following what I said above, dangerous features should not be restricted, they should be made cumbersome. The path of least resistance should be safe, and it should take effort to go the dangerous route.
Pointer arithmetic is plainly a mistake. That T * has no size component and that it can be arbitrarily added to to obtain another T * is just looking for trouble. The type of a single pointer and the type of a pointer to an array should be entirely unrelated. I would imagine it like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
T *p = new T;
//Equivalently: T[1] *p = new T;
T[14] *p2 = new T[14];
assert(p2.size() == 14);
T[] *p3 = new T[n];
assert(p3.size() == n);
T[13] *p4 = p2 + 1;
assert(p3.size() == 13);
//Equivalently, T[13] *p4 = p2.slice(1);
T[] *p5 = p4;
assert(p5.size() == 13);

//f(p + _);         //Error
//f(p[_]);          //Error
f(p2[13]);
//f(p2[14]);        //Error
//f(p2[i]);         //Error. No bounds checking.
if (i >= 0 && i < p2.size())
    f(p2[i]);       //OK?
f(p2.at(i));        //Bounds-checked
f(p3[x]);           //Bounds-checked
f(p3.slice(x, 1));  //Bounds-checked 
A T[N] * should be explicitly convertible to, say, std::legacy::pointer<T> that behaves as a naked pointer.
//f(p2[i]); //Error. No bounds checking

I'd honestly hate that. It's prioritizing safety over the expediency of me coding.

This is the same reason I don't agree with making the dangerous features more cumbersome. No - make the safe features more convenient!

I don't think either of us is right or wrong, we simply disagree on priorities.

However, I will point out that it is always historically better to make the "right" choice convenient, easy, and simple rather than forcing the right choice onto people. Hence, again, why I say make the safer options convenient, don't force me into playing by your rules.
It's prioritizing safety over the expediency of me coding.
The operator doesn't check bounds at run time, it defers them to the compiler. If the compiler can't determine if an access is within bounds because the RHS operand is dynamic, the only alternative is to reject the program. Would you rather that indexing a statically-sized array require bounds check at run time by default?

it is always historically better to make the "right" choice convenient, easy, and simple
I agree. Which is why I think the default behavior of the indexing operator (i.e. the most common way to access sequences) should be to check bounds. Since there's only one indexing operator, there's no way to make the safe behavior convenient without making the less safe behavior less convenient.

In an existing language, there's no way to encourage a safe writing style that doesn't involve making unsafe practices at least a little more inconvenient. That's why people use linters that catch probable errors and that are not completely trivial to turn off. Like I said, the "point at foot" switch should not be so easy to flip that merely picking up the gun does it. It should take at least a little bit of ceremony for you to confirm that yes, you want to point the gun at your foot and you'll be careful not to pull the trigger.
Again, it's not like C++ never introduced its own incantations to appease the compiler. Its type system is stronger than C's. This:
 
double *arr = (double *)malloc(/*...*/);
is a bit more ceremonious than this:
 
double *arr = malloc(/*...*/);
but I think we can all agree that the compiler not letting us implicitly cast unrelated pointers between each other is good, despite most of the casts we use being valid.
Last edited on
Would you rather that indexing a statically-sized array require bounds check at run time by default?

We don't need to check at all without the programmer's explicit determination that they want checking.

However.. If we MUST have it.. Most bounds error checking can happen at compile-time. Then off-load that which can't happen at compile-time to run-time. This would be a minority of cases and likely never affect performance.

This way, you have your bound-checking mandate, and I don't have to change how I want to code something because I'm assumed to make a mistake before I make it.

I agree. Which is why I think the default behavior of the indexing operator (i.e. the most common way to access sequences) should be to check bounds

Does it inconvenience the way I code? Yes. Does it assume I'm a dumbass? Yes. Then it's not something I'm for as it would be the opposite of what I said - it doesn't make the right way convenient, this is forcing the "right" way on me.

That's why people use linters that catch probable errors

Now, there's a BIG difference between stopping me from coding a certain way JUST because it has the capacity to be wrong versus giving me an error because something in my code is very very likely to be incorrect.

I would not be against some errors that arise from an intelligent (likely heuristic-driven) algorithm that thinks I made a fatal error. But it SHOULD be easy to dismiss. I should just be able to say, "no that wasn't an error" and be on my way.

I think we can all agree that the compiler not letting us implicitly cast unrelated pointers between each other is good

I'm not really sure what you mean.

Compiler checking allows you to be sure that you're allocating and setting things correctly by the compiler. It's not about casting. If you wanted to do something completely different, it doesn't take anymore effort to cast anyway you want:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
    // Cast however you want?
    double* arr = reinterpret_cast<double*>(malloc(100));
    float* arr2 = reinterpret_cast<float*>(arr);

    // Doesn't care if you cast nonsensically?
    int* ptr = new int(10);
    void* voidPtr = (void*)ptr;
    char* charPtr = (char*)voidPtr;

    // Doesn't care about type?
    double a = 'a';

    // Do you mean this is not allowed?
    int* testPtr = (char*)charPtr;

    return 0;
}


If you want protection you use static_cast. This is a perfect example of making the right way convenient while fully allowing me every opportunity to do things anyway I see fit. I find no issue in using static_cast.

Trying to do int* = (char*) would almost certainly lead to undefined behavior and will never be what someone wants. Let me elaborate, why cast a pointer to one type to store it in another type? There is no possible benefit from this as your cast was pointless. Hence, this is not something anyone would ever even do, it makes no sense.


Trump was elected, think we need to start a thread on that idiocy.
the papers have it covered. Nothing has signaled the death of journalism like the 'the end is here' headlines in 95% of the online rags and big news videos etc. Its kinda funny.. they highlight the very things that got him elected as a problem -- oh noes, abortion abortion and more abortion .. when people who can no longer afford to buy food are busy voting for the other guy, the media egg heads are all in a tizzy over whether we may lose the dubious 'right' to murder children. We may need it, though, since we can't afford to feed them... Other places are like 'he may weaponize government to go after his enemies' as if the last 6 years have not been a case study in exactly that against him**. Probably 75% of the idiots on jan 6 were just there to yell and shake their fists, but someone got a door open and things got rowdy. Less rowdy than most of the BLM or Occupy riots, but worse than it should have been. The lefties used every tool possible to prosecute everyone they could find in that crowd to the harshest extent of the law while the guys that were shooting at the police in BLM events walk free. The lefties mobilized banks (prevent loans or business or accounts) and the law (sue the manufacturer) and the EPA (lead is bad!) against the gun industry. Almost everything the goom and doomers are preemptively accusing trump of going to do, they have been doing for 6 years. That includes the racist stuff, where the left has coined an entire movement (diversity and inclusion) whos sole purpose is to prevent straight "white" men from getting or keeping a job.

Other crap... ageism .. the same people that let biden be complain about trump's age, and those are the same ones who attacked mccain on age... the age thing on trump is possibly the biggest whisky tango foxtrot of them all. He probably IS too old, but there isnt a leg to stand on here when fussing about it.

I hate trump, by the way. I am just calling out the BS where I see it. Once he takes office, there will be plenty of BS to pick at without making it up ahead of time. And yea, I will keep voting red even when I hate the candidate and feel we have the worst possible moron in the country on the ballot... and I will keep doing it until the words "white", "assault rifle", "gun violence", and "gun control" are stricken from the lefty agenda.

I am a very frustrated libertarian. I thought we hit rock bottom with trump vs hillary, but this year was lower still.

**I don't deny he broke the law and I don't mind him being locked up for it, but it has to be equal. HRC, Hunter Biden, Obama, B. Clinton, and others flaunted their lawbreaking repeatedly. Only trump is being called on it.
Last edited on
Trump was elected, think we need to start a thread on that idiocy.

If that happens I am out'a here. Not much of a threat, but there it is.

CPlusPlus was the last refuge from the idiocy elsewhere. Keep it a safe haven for programming only.
If that happens I am out'a here. Not much of a threat, but there it is.

CPlusPlus was the last refuge from the idiocy elsewhere. Keep it a safe haven for programming only.

The lounge has always been a safe haven for anything. I don't feel like there's many other forums for discussion I can even turn to for such topics.

You don't have to participate in them, that's understandable, but you don't have to leave the entire forum :(

Other places are like 'he may weaponize government to go after his enemies' as if the last 6 years have not been a case study in exactly that against him...

Almost everything the goom and doomers are preemptively accusing trump of going to do, they have been doing for 6 years

This is simply not true. No one is perfect, and their policies may have negative effects that swing issues the other direction, but that is completely different from the "accusations" on what Trump would do.

Trump himself has stated he would be a dictator, wants military leaders like Hitler had (so he could not only weaponize the government against his enemies but the literal military as he has stated many times), has lead a blatantly fascist movement, conversed with U.S. foreign enemies (Putin) while NOT in office, etc..

When the EU (our allies) has to put a task force to "deal" with Trump while Putin (our enemy) is congratulating Trump and saying he'd love to talk with him, you should be concerned.

There is nothing Putin would love more than to bring down the leader of the free world, not through war, but through the same corruption that we claimed to fight against.

Probably 75% of the idiots on jan 6 were just there to yell and shake their fists, but someone got a door open and things got rowdy. Less rowdy than most of the BLM or Occupy riots, but worse than it should have been.

I'm sorry, but this is a complete denial of reality. Trump knew the protest would turn violent, let it turn violent, had to be urged for over 3 hours of violence that he needs to tell them to leave before he decided to.

Trump cited an insurrection to "hang Mike Pence" specifically because democracy did not work in his favor. Convincing people that democracy has failed them and that no news-source or media will be honest except for him is a fascist regime that should disqualify him for office.


Then you have him actually winning the election. When the media fact-checks him, it's election interference, but when Elon Musk spreads right-wing propaganda on the daily by literally buying a huge social media platform, this is just fair-play. The election was bought with money and information warfare.


You need not think that democrats are perfect to recognize the idiocy of Trump - where his own administration refuses to work with him again, where he was deemed incompetent by every person in government that was forced to deal with him. Trump is a man who refused to send aid to a state after a natural disaster because it was blue, having to be convinced by white-house staff by showing him that voters in the affected area were his supporters.


Arguments like yours are the EXACT reason it has become such a meme that undecided voters are struggling between picking a good - but perhaps not great - option, and literally rat poison.
Last edited on
Talking politics, period, is a bridge too far. Participation or not.
Normally politics is not my discussion of choice, but being against fascism is hardly a political viewpoint.

Talking about Hitler in history class is never a political discussion. It's not a disagreement on policy. This particular discussion is a disagreement against a man who is not only extremely similar to Hitler, but has been compared to Hitler by himself and his VP.

I think it's an important discussion. There's a quote floating around:

Dear America: You are waking up, as Germany once did, to the awareness that 1/3 of your people would kill another 1/3 while 1/3 watches


I don't necessarily think Trump will become the next Hitler, but not from lack of trying on his part. That is an important discussion to be had, and the lounge is traditionally for anything non-coding related.

I don't want you to leave George, but I also think it's an important discussion to be had.
Arguments like yours are the EXACT reason it has become such a meme that undecided voters are struggling between picking a good - but perhaps not great - option, and literally rat poison.


Except where I sit, it was lethal poison on both sides.

I also don't want to offend George so I will keep it short. First, I agree with more of what you said than you probably expect but will skip over rehashing it other than to say my main point was that journalism has been a casualty early in this 'war'.

I think the key takeaway from the counterpoints above is that trump should have been disqualified to begin with, not allowed into the primary in the first place. Someone dropped the ball there. And then he somehow won the primary, which also should never have happened (the voters choked). But the big blue vs red .. that one makes sense. Both sides see their rights under constant attack and fear/anger at the other side, but the cost of food and gas and basic economics never fail in these contests... the party in charge when the economy goes south gets the boot every time. There is more to it than that, but you can't underestimate an angry electorate and you certainly don't want to take them for granted...

I will throw a little hope out too. In 4 years, he is gone. The career politicians (congress) won't risk their futures for this man. I hope I am right here.. but if so, all he can really do is sign what they send him & make an ass of himself on the X.
Last edited on
IMO politics should not be 'off topic' for the Lounge as long as views expressed are polite and respectful for different point of views from others.

However bringing a thread called 'New Safe C++ Proposal' into the area of politics does seem like thread hijacking. If members want a polite discussion re politics then may I suggest you start your own thread(s) and stop hijacking others please.
Wow. Things went off the deep end, eh?

If we MUST have it.. Most bounds error checking can happen at compile-time. Then off-load that which can't happen at compile-time to run-time. This would be a minority of cases and likely never affect performance.
But "the bounds checking that can't happen at compile time" is not a fixed set. It depends on how smart the compiler is. What should a toolchain with no optimizer do? Reject the code or generate a bounds check? The former is what I went with. The latter is the alternative I gave you. Semantics-preserving optimizations are always possible, but you need to define the semantics first.

Does it inconvenience the way I code? Yes.
How does bounds checking inconvenience you?

Does it assume I'm a dumbass?
You are a dumbass. It is right to assume that. You sometimes forget to do things or forget you've done things, and you don't know some things and you don't know you don't know other things.

Then it's not something I'm for as it would be the opposite of what I said - it doesn't make the right way convenient, this is forcing the "right" way on me.
Okay, but what exactly is the cost? Suppose you were dropped into a project and you had to use this hypothetical language. Would you be actively going out into the weeds just to turn off safety features? I really don't understand what you're complaining about. Any language by its design imposes a default style. I assume you don't write programs with goto as the primary control flow feature, even though nothing stops you. So what exactly are you complaining about? Honestly, it sounds like a "off-road truck driver driving on highway" sort of thing to say.

Now, there's a BIG difference between stopping me from coding a certain way JUST because it has the capacity to be wrong versus giving me an error because something in my code is very very likely to be incorrect.
So I assume you don't use RAII, then. After all, manually managing your resources just has the capacity to be incorrect.

If you wanted to do something completely different, it doesn't take anymore effort to cast anyway you want
It literally takes more effort to type a cast that to not type it.

If you want protection you use static_cast. This is a perfect example of making the right way convenient while fully allowing me every opportunity to do things anyway I see fit.
I actually think it's a perfect example of how not to do it, because in every case where a cast is needed (other than dynamic_cast) it's more convenient to use a C cast than to use any other cast, even though a C cast makes the compiler less able to inspect the operation.

Trying to do int* = (char*) would almost certainly lead to undefined behavior and will never be what someone wants. Let me elaborate, why cast a pointer to one type to store it in another type? There is no possible benefit from this as your cast was pointless. Hence, this is not something anyone would ever even do, it makes no sense.
That was a bad example. While dereferencing the int pointer does indeed have undefined behavior, any usable compiler would have to define it in its implementation or else it could possibly break swaths of code that deserialize data structures by casting byte buffers to PODs.
I will throw a little hope out too. In 4 years, he is gone.

Some people worry that won't be the case.


Wow. Things went off the deep end, eh?

such is life

So what exactly are you complaining about? truck driver driving on highway" sort of thing to say.

This is not a bad comparison. People buy off-roading vehicles, even though they'll spend 99% of their time driving on a regular road. That 1% matters, it's why they bought it!

It is right to assume that.

Who else should assume this? Assume every programmer is a dumbass and reject all their code without 3rd party verification.

How does bounds checking inconvenience you?

If it rejects code that does not have bounds checking then that is an inconvenience - it forces code rewrite if you did something a certain way.

This is why I would not be against the alternative I presented which gives guaranteed bounds but at no expense to the programmer.

Suppose you were dropped into a project and you had to use this hypothetical language. Would you be actively going out into the weeds just to turn off safety features?

No, that would be bad practice after-all. However, I find it very annoying when I have a program planned out in my head but a different language forces me to do it some other way in order to play by its rules.

I can write the code from other languages in C++, I can't write all C++ in those other languages, that's the inconvenience.

So I assume you don't use RAII, then. After all, manually managing your resources just has the capacity to be incorrect.

Obviously we use RAII due to the convenience way just as much if not more so for the safety. Safety that's also convenient - that's just perfection.

It literally takes more effort to type a cast that to not type it.

You have to type to do a cast anyway, C++ is an explicit language. Each type of cast just has a different syntax, not sure what the argument here is.

I actually think it's a perfect example of how not to do it, because in every case where a cast is needed (other than dynamic_cast) it's more convenient to use a C cast than to use any other cast

Very valid actually. I don't find the little extra typing to be that crazy, but I do end up using c-style casting more than the safer casting. I wouldn't particularly mind having c-style casts become "safer", but it would probably break backwards compatibility in the language.

Now, yes, writing out "static_cast" or "dynamic_cast" or whatever takes a tiny bit more effort than (double*). However, this is not the kind of thing that would force you into changing the logic of your program, it is simply a small syntax difference. This is an acceptably small sacrifice for extra safety.

While dereferencing the int pointer does indeed have undefined behavior, any usable compiler would have to define it in its implementation

This is besides the point. If you have a char array that you want to cast to an int array, you can do so, just cast.

Again, C++ is an explicit AND statically typed language. You're simply not allowed to set one type of variable with a variable of another type. To do so requires a cast. Unless you want C++ to implicitly cast for you, then it makes complete sense not to allow something like int* = &charArray.

Even the other casts would not allow you to set a variable type with that of another type, you have to cast it to the correct type first.


You cannot argue for safety by saying that any feature or trait of C++ that has safety as a byproduct I must be against somehow. Again, I'm 100% for safety, just don't make me change how I code. Don't make me bend around safety, have the safety bend around me. That sounds odd.

Don't make me write recursive solutions that can overflow dangerously, have defined behavior. Don't let my integers overflow randomly, have defined behavior.

Check for bounds errors at compile time? Sure, but don't reject my code at compile-time just because you couldn't be 100% sure if my bounds were safe or not. Generate a bounds check in the background? Fine, no problem, it'll only trigger if I screw up.

Do you see the difference? I want safety to only kick in when I screw up, not just when I engage in programming where I might screw up.
Last edited on
People buy off-roading vehicles, even though they'll spend 99% of their time driving on a regular road. That 1% matters, it's why they bought it!
I'm not saying "driving off-road" should be impossible, I'm saying it should not be as convenient as "staying on the highway" (that is to say, not so convenient it can happen without you even realizing it). If you're admitting that 99% you'll stay on the road then it shouldn't be a problem if your off-road-capable car requires you to stop for five minutes to change a setting on the suspension prior to getting off the road for that 1%, and otherwise the car will simply refuse to drive off the road.

Assume every programmer is a dumbass and reject all their code without 3rd party verification.
Code audits are not as good as the formal verification compilers perform. I should know, I have worked for a company that does them.

Obviously we use RAII due to the convenience way just as much if not more so for the safety. Safety that's also convenient - that's just perfection.
I don't necessarily agree RAII is always more convenient. In some cases finalizers are more convenient than all the destructor boilerplate.

You have to type to do a cast anyway, C++ is an explicit language. Each type of cast just has a different syntax, not sure what the argument here is.
But in C you just implicitly convert any pointer type to any other pointer type no matter how much sense it makes. So convenient! Surely you would love not having to bother with all the ceremony C++ imposes just for the sake of "safety". Eugh! What a hassle, right?

You're simply not allowed to set one type of variable with a variable of another type. To do so requires a cast. Unless you want C++ to implicitly cast for you, then it makes complete sense not to allow something like int* = &charArray.

Even the other casts would not allow you to set a variable type with that of another type, you have to cast it to the correct type first.

You cannot argue for safety by saying that any feature or trait of C++ that has safety as a byproduct I must be against somehow.
What I'm saying is that C++ already adds some ceremony compared to its predecessor that increase safety at the expense of convenience. If more was added, it would not make the language's design inconsistent.

Again, I'm 100% for safety, just don't make me change how I code.
That's probably not possible. Pointer arithmetic is a particularly extreme example of something that's highly dangerous and error-prone, and completely un-analizable by the compiler. A safe language just cannot have it.

I want safety to only kick in when I screw up, not just when I engage in programming where I might screw up.
Thanks for summing it up. I guess that's where we differ. I want a safe language. You want a safer language.
Last edited on
then it shouldn't be a problem if your off-road-capable car requires you to stop for five minutes to change a setting on the suspension

Obviously this is would not be ideal. Ideally you could just go from a highway to off-roading without a second thought.

I don't necessarily agree RAII is always more convenient.

Maybe, but a good way of organizing code and memory. Safety + convenience.

Surely you would love not having to bother with all the ceremony C++ imposes just for the sake of "safety". Eugh! What a hassle, right?

Some hassles disproportionately bring safety. When dealing with pointers (particularly double or triple pointers), it is ridiculously easy to try and incorrectly set pointers to a variable that is incompatible.

I use to (and sometimes still do) figure out what kind of pointer variable is needed by just brute force typing out a single * then adding another to see if it works. If not, then I usually use "auto" and see wtf the language thinks is the appropriate variable type. It is just sometimes annoying to figure out exactly how deep the pointer you're holding really is, and it's easy to get wrong.

I haven't really used C like that, so I didn't even know that was a thing. But clearly, we would both agree C is an extremely fragile language when it comes to safety.

I am not against having the safety on the gun. I'm against an unstoppable AI on the gun that tells me I can't shoot when pointing it at my own foot.

What I'm saying is that C++ already adds some ceremony compared to its predecessor that increase safety at the expense of convenience. If more was added, it would not make the language's design inconsistent.

This is a slippery slope. If someone gets a nose-job, you could then use the same argument to say, "well, you already had surgery to make yourself look better. Why not get botox, breast enlargement, lipo-suction, lip fillers, plastic surgery on your ass, etc..)."

Somethings are more necessary than others. Somethings are more impactful than others. Some things are more extreme than others. You have to balance it.

That's probably not possible. Pointer arithmetic is a particularly extreme example of something that's highly dangerous and error-prone, and completely un-analizable by the compiler. A safe language just cannot have it.

Yet there are real benefits to it. This is not just safety, its actively trading a beneficial feature for safety. Yes you can still do it, but having to wrap it into an unsafe context

Thanks for summing it up. I guess that's where we differ. I want a safe language. You want a safer language.

You want a guaranteed safe language, I want a language that guarantees you can be safe.

I don't even think you're position is wrong, I just don't like it!
This is a slippery slope. If someone gets a nose-job, you could then use the same argument to say, "well, you already had surgery to make yourself look better. Why not get botox, breast enlargement, lipo-suction, lip fillers, plastic surgery on your ass, etc..)."
Alright, how about this? "Well, you already had knee surgery to fix your bursitis. Don't you also want elbow surgery for your trapped ulnar nerve, LASIK for your astigmatism, a bypass for your coronary artery disease, and some chemo for that leukemia?" (They've seen better days, okay? Don't stare.) When should you stop treating a sick person to stop yourself from falling into a slippery slope?

I want a language that guarantees you can be safe.
That's such a modest requirement, it's met by every programming language that's ever existed. Really, what language absolutely prevents you from writing correct code? Not even Malbolge can do that.

I don't even think you're position is wrong, I just don't like it!
Well, it can't be wrong. It's a want, an opinion. I can be wrong in thinking C++ needs that, but not in just wanting it.
They've seen better days, okay? Don't stare

At that point, there really isn't any saving them.. The difference between our two examples is one is elective while the other is necessary for survival.

C++ WILL survive. We can debate that point, but we'd both be guessing.

That's such a modest requirement, it's met by every programming language that's ever existed

C++ does not even fit that yet. Again, nothing can be done about integer or stack overflows. Not feasible to just keep checking if you've overflowed yet (and not even possible for stack overflow as far as I know).

I'm 100% for safety. Just don't force me to change how I code, don't make the language unrecognizable. Doing that will surely lose C++ programmers more than safety concerns.
RIP George (ne Furry Guy). Much missed.
I'm 100% for safety. Just don't force me to change how I code

Why do I sense mutual exclusivity?
RIP George (ne Furry Guy). Much missed.

RIP :(

Why do I sense mutual exclusivity?

It is. I'm all for the safety allowable up to that point. This is basically the point of the debate.
Pages: 1... 3456