Pointer restrictions removed up to the level of C (and perhaps a bit more)

475 views
Skip to first unread message

snake5...@gmail.com

unread,
May 17, 2012, 6:40:32 AM5/17/12
to lang-pr...@isocpp.org
I know a lot of die-hard C++ fans are going to be against this, against the evil raw pointers and horrifying potential memory problems etc. but I feel like this is a good step towards making the language useful for a few more situations.

I'd like to see the requirement for extremely verbose explicit casts removed, at least depending on a compiler setting.

Why?
I never liked the need to explicitly state unnecessary things - most pointer types match in terms of format and memory usage anyway (they're just integers, after all). More typing doesn't keep anyone away from messing directly with memory. Hasn't kept anyone away. And shouldn't. If people are writing code in C++, in my opinion it should be a fully functional superset of C, not some bling-bling replica. So basically I want to type less to achieve just about the same thing + cleaner code. Casts shouldn't take so much space that they practically obfuscate the most important bits of information.
Another reason for it is that you're already moving that way with "auto" and lambda functions.

How I imagine it
foo_struct* bar = some_char_ptr;
quite_a_long_name_struct* baz = some_char_ptr + bar->where_is_it;

How it currently is
foo_struct* bar = (foo_struct*) some_char_ptr;
quite_a_long_name_struct* baz = (quite_a_long_name_struct*) ( some_char_ptr + bar->where_is_it ); // note the second set of parentheses - casts require those
// here's a "nicer" alternative:
quite_a_long_name_struct* baz = reinterpret_cast< quite_a_long_name_struct* >( some_char_ptr + bar->where_is_it );

How haters are going to imagine it
#define A foo_struct
#define B quite_a_long_name_struct
A* bar = (A*) some_char_ptr;
B* baz = (B*) ( some_char_ptr + bar->where_is_it );
#undef A
#undef B

P.S. If you're going to bore me with random theory like "pointers could be unique identifiers uncapable of representing anything but the type" then please let me remind you that the second word in "computer science" means experiments, putting stuff into practice and watching it, trying to understand how it works. I've done my fair share of science and for us, low-level programmers, it just doesn't work in such a restricted and impractical way.
P.P.S. I've been informed that accepting such a proposal would mean having many pages of the standard rewritten. I strongly urge you to reconsider it nonetheless.

Ville Voutilainen

unread,
May 17, 2012, 6:56:43 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 13:40, <snake5...@gmail.com> wrote:
> I'd like to see the requirement for extremely verbose explicit casts
> removed, at least depending on a compiler setting.
> Why?
> I never liked the need to explicitly state unnecessary things - most pointer

Then don't. Write something like

template <class T> struct unsafe_ptr
{
T* ptr_;
unsafe_ptr(void* vptr) : ptr_((T*)(vptr)) {}
unsafe_ptr(char* vptr) : ptr_((T*)(vptr)) {}
T* operator->() {return ptr_;}
operator T*() {return ptr_;}};
}

and use unsafe_ptr<foo_struct> and unsafe_ptr<quite_a_long_name_struct>.
And if you want, do a template <class T> using XXX = unsafe_ptr<T> and then
you can just write XXX<quite_a_long_name_struct> instead.

It'll be a cold day in hell before the standard is changed to allow
such conversions
implicitly, and whether they are unnecessary is highly debatable. So,
if you want
to have something more implicit, you can write your own pointer
handles to achieve
exactly that.

Ville Voutilainen

unread,
May 17, 2012, 6:58:16 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 13:56, Ville Voutilainen <ville.vo...@gmail.com> wrote:
> template <class T> struct unsafe_ptr
> {
>  T* ptr_;
>  unsafe_ptr(void* vptr) : ptr_((T*)(vptr)) {}
>  unsafe_ptr(char* vptr) : ptr_((T*)(vptr)) {}
>  T* operator->() {return ptr_;}
>  operator T*() {return ptr_;}};
> }

A slight copy-paste error at the end, with a superfluous semicolon. :)

snake5...@gmail.com

unread,
May 17, 2012, 7:16:07 AM5/17/12
to lang-pr...@isocpp.org
On Thursday, May 17, 2012 1:56:43 PM UTC+3, Ville Voutilainen wrote:
Then don't. Write something like...

You're offering me to replace explicit casts with a different kind of explicit casts? Come on, that doesn't solve any of the mentioned problems. If anything, it obfuscates the source even more. One more pointless object to keep in mind.

Ville Voutilainen

unread,
May 17, 2012, 7:19:50 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 14:16, <snake5...@gmail.com> wrote:
> On Thursday, May 17, 2012 1:56:43 PM UTC+3, Ville Voutilainen wrote:
>> Then don't. Write something like...
> You're offering me to replace explicit casts with a different kind of
> explicit casts? Come on, that doesn't solve any of the mentioned problems.

I'm offering you to replace explicit casts with shorter ones, and not needing to
have them on the right side of initialization. You're not going to get
a language change,
so you should be looking for a work-around instead.

Ville Voutilainen

unread,
May 17, 2012, 7:35:55 AM5/17/12
to lang-pr...@isocpp.org
Regarding "not solving any of the mentioned problems", you don't need
parens on the
right side of assignment/initialization, and

// how you imagine it
foo_struct* bar = some_char_ptr;
quite_a_long_name_struct* baz = some_char_ptr + bar->where_is_it;

becomes
XXX<foo_struct> bar = some_char_ptr;
XXX<quite_a_long_name_struct> baz = some_char_ptr + bar->where_is_it;

but if that's not good enough, there's very little more that can be done.

Chris Jefferson

unread,
May 17, 2012, 7:46:00 AM5/17/12
to lang-pr...@isocpp.org
At the end of the day there is a trade-off. You suggestion isn't "free", it allows a large set of possible bugs to sneak into programs. Early in the design of C++, the decision was made, on purpose, to tighten up pointer restrictions, which you now wish to send the other way.

The issues to do with standard text, or details of how implementations handle pointers, are not particularly major in this case. The much bigger problem would be convincing people that the loss in safety was worth saving a few characters when doing pointer casting, something most people don't do that often.

There are lots of little fiddly issues about your idea which worry me. For example, should I be able to pass an int* to a function that accepts double*? (it seems unlikely anyone would ever do that on purpose, to me at least). When a 'dynamic_cast' would be more appropriate, should a pointer->pointer cast do that instead?


Chris

snake5...@gmail.com

unread,
May 17, 2012, 7:48:54 AM5/17/12
to lang-pr...@isocpp.org
On Thursday, May 17, 2012 2:19:50 PM UTC+3, Ville Voutilainen wrote:
I'm offering you to replace explicit casts with shorter ones, and not needing to
have them on the right side of initialization. You're not going to get
a language change,
so you should be looking for a work-around instead.

This is the proposal group so I'm taking my chances with a more appropriate action. 

Ville Voutilainen

unread,
May 17, 2012, 7:53:01 AM5/17/12
to lang-pr...@isocpp.org
By all means. I know enough about the design&evolution of c++ and how
the committee
would see such a proposal that I can't encourage spending time on it.
It won't pass.

snake5...@gmail.com

unread,
May 17, 2012, 8:02:43 AM5/17/12
to lang-pr...@isocpp.org
On Thursday, May 17, 2012 2:46:00 PM UTC+3, Chris Jefferson wrote:
There are lots of little fiddly issues about your idea which worry me. For example, should I be able to pass an int* to a function that accepts double*? (it seems unlikely anyone would ever do that on purpose, to me at least). When a 'dynamic_cast' would be more appropriate, should a pointer->pointer cast do that instead?

Loss in safety? Do the people who fear pointers actually use them? The function should ask for a reference to a vector instead, if the fear of pointers is so contagious at that area.
And does int* -> double* really pose such a threat? Are people really interested in buffer-to-buffer conversions? That said, I don't see the practical side of your example.

Herb Sutter

unread,
May 17, 2012, 8:44:51 AM5/17/12
to lang-pr...@isocpp.org


Herb


On May 17, 2012, at 6:02 AM, "snake5...@gmail.com" <snake5...@gmail.com> wrote:

On Thursday, May 17, 2012 2:46:00 PM UTC+3, Chris Jefferson wrote:
There are lots of little fiddly issues about your idea which worry me. For example, should I be able to pass an int* to a function that accepts double*? (it seems unlikely anyone would ever do that on purpose, to me at least). When a 'dynamic_cast' would be more appropriate, should a pointer->pointer cast do that instead?

Loss in safety? Do the people who fear pointers actually use them?

Yes.

The function should ask for a reference to a vector instead, if the fear of pointers is so contagious at that area.

Can you explain the rationale for why this proposal would treat pointers and references differently?

Herb

snake5...@gmail.com

unread,
May 17, 2012, 9:16:38 AM5/17/12
to lang-pr...@isocpp.org
Alright, I'd agree that they might use the occasional c_str(). But as far as pointers to objects are concerned, even if they're using pointers, they are seriously avoiding them. Haven't seen a better explanation for the numerous variations of pointer data types that have been created almost exclusively for C++.


On Thursday, May 17, 2012 3:44:51 PM UTC+3, Herb Sutter wrote:

Can you explain the rationale for why this proposal would treat pointers and references differently?


As far as the treatment of pointers and references is concerned, the proposal addresses only the act of changing the memory address of the pointer, the one feature that references do not have. 

Ville Voutilainen

unread,
May 17, 2012, 9:21:40 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 16:16, <snake5...@gmail.com> wrote:
>> Can you explain the rationale for why this proposal would treat pointers
>> and references differently?
> As far as the treatment of pointers and references is concerned, the
> proposal addresses only the act of changing the memory address of the
> pointer, the one feature that references do not have.

The examples you gave were initializations, not assignments.

Ville Voutilainen

unread,
May 17, 2012, 9:31:26 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 16:21, Ville Voutilainen <ville.vo...@gmail.com> wrote:
>> As far as the treatment of pointers and references is concerned, the
>> proposal addresses only the act of changing the memory address of the
>> pointer, the one feature that references do not have.
> The examples you gave were initializations, not assignments.

At any rate, a core language change proposal should describe the exact
rationale,
and explain what the impact of the change would be, including the impact for
existing code. Proposing anything that decreases type safety needs particular
care. This idea has about a snowball's chance in hell to be adopted,
so I strongly
urge to focus your energy elsewhere.

snake5...@gmail.com

unread,
May 17, 2012, 9:53:53 AM5/17/12
to lang-pr...@isocpp.org
On Thursday, May 17, 2012 4:21:40 PM UTC+3, Ville Voutilainen wrote:

The examples you gave were initializations, not assignments.

Which work exactly the same way as assignments with pointers. No difference should come out of creating an object separately and assigning to it on the next line.

The rationale was explained in the first post: this change aims to make written code that involves casts easier to read and understand, and, most importantly, write. Nothing stops you from adding an explicit cast if you desire to do so.

I see a lot of concern about this "security" that the existing system provides. Perhaps you have any practical examples of where it saved development/testing time?

Ville Voutilainen

unread,
May 17, 2012, 9:59:49 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 16:53, <snake5...@gmail.com> wrote:
>> The examples you gave were initializations, not assignments.
> Which work exactly the same way as assignments with pointers. No difference

For references they don't. If you intend to make such a change for assignments
but not initializations, you should say so. If it's intended to apply
to pointers but
not to references, you should say so and explain why.

> I see a lot of concern about this "security" that the existing system
> provides. Perhaps you have any practical examples of where it saved
> development/testing time?

We do.

char* allocate_raw_mem();

struct B {};

B* obj = allocate_raw_mem();

It saves time that I don't have to debug the resulting undefined behavior when
I try and dereference obj. Same goes for

struct C {}; // completely unrelated to B
C c;
B* b = &c;

Chris Jefferson

unread,
May 17, 2012, 10:01:39 AM5/17/12
to lang-pr...@isocpp.org
Such examples are very hard to come by.

I must have had hundreds, perhaps thousands, of compiler errors over the year because I was passing the wrong type (both pointers, and non-pointers) to a function, or assigning the wrong type to a variable. In each case I fixed it up. I believe the times I wanted to add a pointer cast was a tiny fraction of those.

While I realise this is not what you want to hear, this particular point was discussed at length many years ago. It did cause a lot of pain, as it was one of the most obvious ways in which C code was not valid C++. I can assure you (as had been said) there is absolutely no chance of C++ going back to C-like type unsafety. Sorry.

Chris

snake5...@gmail.com

unread,
May 17, 2012, 10:24:36 AM5/17/12
to lang-pr...@isocpp.org
I proposed the change to pointer casts which implicitly include assignments and initializations of pointers.

What I'm saying is that it shouldn't be undefined behavior. In practice, it is defined. Again, I said it in the first post. It seems to me that you're dismissing the proposal too quickly.

And your examples don't make any sense, at least not in the context you provide. With header-like structures, the second example would make sense to use. And it's also where it would work best. With something else, it is extremely obvious from the code that it would not work well. That's the kind of clarity I'm trying to achieve with my proposal. No hidden magic and false security.

Ville Voutilainen

unread,
May 17, 2012, 10:31:30 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 17:24, <snake5...@gmail.com> wrote:
> I proposed the change to pointer casts which implicitly include assignments
> and initializations of pointers.
> What I'm saying is that it shouldn't be undefined behavior. In practice, it

If I assign a pointer to C to pointer to B, and the types are
completely unrelated
and of different size, of course it's undefined behavior to
dereference a pointer
when the actual underlying type is something completely different. It
can't work,
in practice or in theory. That's the whole point of forbidding it.

> is defined. Again, I said it in the first post. It seems to me that you're
> dismissing the proposal too quickly.

Oh, I've given it more time than it deserves.

> And your examples don't make any sense, at least not in the context you
> provide. With header-like structures, the second example would make sense to

They are simplified. Allowing such conversions blindly would cause no end of
harm, trouble and lost time.

Ville Voutilainen

unread,
May 17, 2012, 10:36:26 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 17:31, Ville Voutilainen <ville.vo...@gmail.com> wrote:
> They are simplified. Allowing such conversions blindly would cause no end of
> harm, trouble and lost time.

Do you really want to allow

struct C { int x; int y; };

C* c = new char[1];

?

Do you want to allow

struct B {};

B b;
C* c = &b;

?

In both cases, trying to dereference c will just explode. Such mistakes
are extremely common, and there are very good reasons why neither C nor C++
allow those without explicit casting.

snake5...@gmail.com

unread,
May 17, 2012, 11:03:50 AM5/17/12
to lang-pr...@isocpp.org
Null pointer dereferencing is even more common. Should we restrict using those, too? What's next? Oh, dangling pointers, let's remove those too. What's next? We've got a new flavor of C#. But wait, someone could hurt himself with compile warnings, let's not allow that... 

All kidding aside, unless struct C would ever contain a char, I have no intention of following your example. Neither does any programmer in the world. So your idea really is to protect them from something they do not want to do by using obnoxious restrictions.

And what exactly doesn't C allow? http://codepad.org/AWMYcMV2

Ville Voutilainen

unread,
May 17, 2012, 11:05:57 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 18:03, <snake5...@gmail.com> wrote:
> All kidding aside, unless struct C would ever contain a char, I have no
> intention of following your example. Neither does any programmer in the
> world. So your idea really is to protect them from something they do not
> want to do by using obnoxious restrictions.

Programmers attempt to assign incompatible pointer types all the time.
Your idea is to allow it because is some once-in-a-blue-moon rare cases
it works. There's ample evidence that those are indeed rare cases, and
the language is right to reject them and require an explicit cast.

snake5...@gmail.com

unread,
May 17, 2012, 11:11:54 AM5/17/12
to lang-pr...@isocpp.org
All the time? I'd like to hear that job description, sounds awesome.

It doesn't happen more than assigning wrong data to variables happens while writing code in dynamically typed languages. And those cases are indeed rare. So I have no idea where you got your statistics but they don't match the situation that I see.

Ville Voutilainen

unread,
May 17, 2012, 11:19:01 AM5/17/12
to lang-pr...@isocpp.org
On 17 May 2012 18:11, <snake5...@gmail.com> wrote:
>> Programmers attempt to assign incompatible pointer types all the time.
> All the time? I'd like to hear that job description, sounds awesome.
> It doesn't happen more than assigning wrong data to variables happens while
> writing code in dynamically typed languages. And those cases are indeed
> rare. So I have no idea where you got your statistics but they don't match
> the situation that I see.

I get those statistics from programming for two decades. I do it
myself all the time,
accidentally. The language stops me before I get to run the program, which saves
time. Other programmers do similar things accidentally. The situation
would become
much worse if such conversions are allowed and templates are involved.

You can make as many snide remarks as you want. The benefit of allowing such
conversions is much smaller than the cost of it would be. Happily, such a change
won't be made, and people will have to write the casts explicitly, which also
serves the purpose of making such conversions noticeable in code.

Christopher Jefferson

unread,
May 17, 2012, 11:30:24 AM5/17/12
to lang-pr...@isocpp.org

On 17 May 2012, at 16:03, snake5...@gmail.com wrote:
>
> Null pointer dereferencing is even more common. Should we restrict using
> those, too? What's next? Oh, dangling pointers, let's remove those too.
> What's next? We've got a new flavor of C#. But wait, someone could hurt
> himself with compile warnings, let's not allow that...

While you said kidding, I think these examples are interesting. If there was some way of stopping a large set of null pointer dereferences, or dangling pointers, at compile time without being too annoying (and I realise that is a difficult thing to measure), I think they would be seriously considered for C++. Unfortunately at this point such things would likely break a large set of code.

std::shared_ptr and std::unique_ptr (and the now abandoned std::auto_ptr) are all attempts at dealing with both dangling pointers and memory leaks.

> All kidding aside, unless struct C would ever contain a char, I have no
> intention of following your example. Neither does any programmer in the
> world. So your idea really is to protect them from something they do not
> want to do by using obnoxious restrictions.

At the end of the day, we are going to annoy one of two groups of people:

1) If we leave C++ as is, people like yourself who want to cast pointers implicitly who get annoyed by having to put casts everywhere.

2) If we change C++, we will annoy people who accidentally write incorrect code which turns one pointer type into another.

I assume you believe there are more people in category (1) than category (2), and that the annoyance from (2) isn't too bad, compared to the annoyance from (1).

We disagree with you. You would have to come up with some really, really, really convincing evidence to change people's mind that we should annoy group (2) instead of group (1).

Chris

Herb Sutter

unread,
May 17, 2012, 12:06:01 PM5/17/12
to lang-pr...@isocpp.org
On May 17, 2012, at 9:30 AM, Christopher Jefferson
<ch...@bubblescope.net> wrote:

>
> On 17 May 2012, at 16:03, snake5...@gmail.com wrote:
>>
>> Null pointer dereferencing is even more common. Should we restrict using
>> those, too? What's next? Oh, dangling pointers, let's remove those too.
>> What's next? We've got a new flavor of C#. But wait, someone could hurt
>> himself with compile warnings, let's not allow that...
>
> While you said kidding, I think these examples are interesting. If there was some way of stopping a large set of null pointer dereferences, or dangling pointers, at compile time without being too annoying (and I realise that is a difficult thing to measure), I think they would be seriously considered for C++. Unfortunately at this point such things would likely break a large set of code.
>
> std::shared_ptr and std::unique_ptr (and the now abandoned std::auto_ptr) are all attempts at dealing with both dangling pointers and memory leaks.

Actually, what Snake said in jest is not only exactly where we are
going, but where we now are with C++11.

Now that we have usable standard smart pointers (unique and shared) we
are indeed now beginning to consider broadly recommending "never write
new or delete by hand (unless in the internals of implementing a low
level data structure)"! Use make_shared (or make_unique which is
missing) instead of new, and deletes are automatic. In that
memory-safe world there are indeed no dangling pointers, no
use-after-delete, and no uncheckable null derefs.

And as a next step, getting rid of pointer arithmetic entirely is on
my personal radar... :) The trouble root cause is that C used the same
type for "points to an object" and "iterates over an array"... imagine
if we had a distinct array_iterator that could iterate over any
contiguous storage (T[], vector<T>, etc.) with bounds checks, to
replace all pointer arithmetic.

Herb
>

snake5...@gmail.com

unread,
May 17, 2012, 12:51:40 PM5/17/12
to lang-pr...@isocpp.org
On Thursday, May 17, 2012 6:19:01 PM UTC+3, Ville Voutilainen wrote:
I get those statistics from programming for two decades. I do it
myself all the time,
accidentally. The language stops me before I get to run the program, which saves
time. Other programmers do similar things accidentally. The situation
would become
much worse if such conversions are allowed and templates are involved.

Now that's interesting. I'm somehow writing C code with all those "dangerous" casts and I've *never* had such a problem myself. You see, correlation does not imply causation. I make less mistakes because I am more careful, and that's because I have less safety nets. From my experience writing business software and computer games, I've deduced that more possibilities for fewer kinds of errors do not lead to more errors. It leads to the exact opposite of that - less errors made, more experience gained. While I was writing C++ only, I could barely step away from safety nets. Guessing it's the same thing with most users. But fear-driven design isn't the future I'd like to see for C++.

snake5...@gmail.com

unread,
May 17, 2012, 1:10:06 PM5/17/12
to lang-pr...@isocpp.org
On Thursday, May 17, 2012 6:30:24 PM UTC+3, Chris Jefferson wrote:

At the end of the day, we are going to annoy one of two groups of people:

1) If we leave C++ as is, people like yourself who want to cast pointers implicitly who get annoyed by having to put casts everywhere.

2) If we change C++, we will annoy people who accidentally write incorrect code which turns one pointer type into another.

I assume you believe there are more people in category (1) than category (2), and that the annoyance from (2) isn't too bad, compared to the annoyance from (1).

We disagree with you. You would have to come up with some really, really, really convincing evidence to change people's mind that we should annoy group (2) instead of group (1).

I'm aware of the overwhelming majority of group #2. But I'm also aware of Sturgeon's law. And I don't think that their fear should be something that is used as foundations of design. Reminds me of religion.

And the funny thing is (well, actually there's a lot of those in every religion) that I'm not asking anyone here to use those unsafe pointers. By all means, wrap them in thousands of objects. Disable that compiler flag to make them safe (I specifically noted that this would be acceptable to me). But I see people acting like I'm forcing them to use all that. This proposal is really about people like me and only such. Because I couldn't care less about those 90% of programmers that I am definitely going to disagree with. At least until I have to work with them.

snake5...@gmail.com

unread,
May 17, 2012, 1:29:19 PM5/17/12
to lang-pr...@isocpp.org
On Thursday, May 17, 2012 7:06:01 PM UTC+3, Herb Sutter wrote:

Actually, what Snake said in jest is not only exactly where we are
going, but where we now are with C++11.

Now that we have usable standard smart pointers (unique and shared) we
are indeed now beginning to consider broadly recommending "never write
new or delete by hand (unless in the internals of implementing a low
level data structure)"! Use make_shared (or make_unique which is
missing) instead of new, and deletes are automatic. In that
memory-safe world there are indeed no dangling pointers, no
use-after-delete, and no uncheckable null derefs.

And as a next step, getting rid of pointer arithmetic entirely is on
my personal radar... :) The trouble root cause is that C used the same
type for "points to an object" and "iterates over an array"... imagine
if we had a distinct array_iterator that could iterate over any
contiguous storage (T[], vector<T>, etc.) with bounds checks, to
replace all pointer arithmetic.

Herb
>

Well, that definitely is disappointing. Compile times are already poor. Feature / LOC ratio is going down. Language complexity is going up. STL is cluttered with all kinds of problems and doesn't seem to get cleaner. It seems that game developers are very soon going to write most of the code in C again. I think getting rid of pointer arithmetic would certainly cause that to happen. However, my proposal could certainly keep me away from using C (yeah, the explicit casts are practically the reason I started writing C instead of C++, and all of those theoretical UBs have also helped me make this decision).

Peter Sommerlad

unread,
May 18, 2012, 1:53:53 AM5/18/12
to lang-pr...@isocpp.org

On 17.05.2012, at 18:06, Herb Sutter wrote:

> Now that we have usable standard smart pointers (unique and shared) we
> are indeed now beginning to consider broadly recommending "never write
> new or delete by hand (unless in the internals of implementing a low
> level data structure)"! Use make_shared (or make_unique which is
> missing) instead of new, and deletes are automatic. In that
> memory-safe world there are indeed no dangling pointers, no
> use-after-delete, and no uncheckable null derefs.

I'll do so in my upcoming "Simple C++" book. There is no need for raw pointers anymore, even if Google's C++ guidelines still tell you so to use pointers instead of references as parameter types.

BTW, I love casting pointers with long and ugly syntax, because it gives me feedback that my design is wrong.

Regards
Peter.
--
Prof. Peter Sommerlad

Institut für Software: Bessere Software - Einfach, Schneller!
HSR Hochschule für Technik Rapperswil
Oberseestr 10, Postfach 1475, CH-8640 Rapperswil

http://ifs.hsr.ch http://cute-test.com http://linticator.com http://includator.com
tel:+41 55 222 49 84 == mobile:+41 79 432 23 32
fax:+41 55 222 46 29 == mailto:peter.s...@hsr.ch





Peter Sommerlad

unread,
May 18, 2012, 1:56:22 AM5/18/12
to lang-pr...@isocpp.org
why don't you just stick with K&R C? Sorry, I am getting upset.
On 17.05.2012, at 19:29, <snake5...@gmail.com> wrote:

> Well, that definitely is disappointing. Compile times are already poor. Feature / LOC ratio is going down. Language complexity is going up. STL is cluttered with all kinds of problems and doesn't seem to get cleaner. It seems that game developers are very soon going to write most of the code in C again. I think getting rid of pointer arithmetic would certainly cause that to happen. However, my proposal could certainly keep me away from using C (yeah, the explicit casts are practically the reason I started writing C instead of C++, and all of those theoretical UBs have also helped me make this decision).

snake5...@gmail.com

unread,
May 18, 2012, 2:44:21 AM5/18/12
to lang-pr...@isocpp.org
Because I find some of the C++'s useful - constructors, templates, the ability to fall back to almost-C. If used carefully (without spamming references and vectors of vectors all over the place), they make code smaller and easier to maintain in those not-quite-low-level codebases like games.

So here's me thinking "what's wrong with trying to make the language I liked so much for such a long time better?"

P.S. Using pointers doesn't make a design wrong, just slightly more low-level. Using lots of unnecessary objects (like most of those that begin with '-er' and '-or'), on the other hand, definitely does that.

Kodt

unread,
May 22, 2012, 4:08:33 PM5/22/12
to ISO C++ Language - Proposals
Explicit stating what exactly do you mean makes the program cleaner
and safer.
That's why there are static_, const_ and reinterpret_ casts in C++,
versus some versatile C cast.

On other hand, most common casts look like that:
Foo foo = some_cast<Foo>(bar); // some_ is static_, dynamic_ or
reinteret_
that is, the parameter of the cast operator matches with the target.

So we can introduce helpers:

template<class Src> struct staticcast_t
{
Src* src_;
staticcast_t(Src* src) : src_(src) {}
template<class Dst> operator Dst* () const { return
static_cast<Dst*>(src_); }
};
template<class Src> staticcast_t<Src> staticcast(Src* src) { return
staticcast_t<Src>(src); }
// and alike helpers for other casts, and for references as well as
for pointers.

Foo* foo; Bar* bar;
foo = staticcast(bar); foo = dynamiccast(bar); foo =
reinterpretcast(bar); // reinterpret can be non-template, just
<void> :)

We can even introduce explicit C-style cast (I don't know why, but yes-
we-can) that does static/const/reinterpret cast depending on types.

foo = cstylecast(bar);

On 17 май, 14:40, snake5crea...@gmail.com wrote:
> I know a lot of die-hard C++ fans are going to be against this, against the
> evil raw pointers and *horrifying **potential *memory problems etc. but I
> feel like this is a good step towards making the language useful for a few
> more situations.
>
> I'd like to see the requirement for extremely verbose explicit casts
> removed, at least depending on a compiler setting.
>
> *Why?*
> I never liked the need to explicitly state unnecessary things - most
> pointer types match in terms of format and memory usage anyway (they're
> just integers, after all). More typing doesn't keep anyone away from
> messing directly with memory. Hasn't kept anyone away. And shouldn't. If
> people are writing code in C++, in my opinion it should be a fully
> functional superset of C, not some bling-bling replica. So basically I want
> to type less to achieve just about the same thing + cleaner code. Casts
> shouldn't take so much space that they practically obfuscate the most
> important bits of information.
> Another reason for it is that you're already moving that way with "auto"
> and lambda functions.
>
> *How I imagine it*
> foo_struct* bar = some_char_ptr;
> quite_a_long_name_struct* baz = some_char_ptr + bar->where_is_it;
>
> *How it currently is*
> foo_struct* bar = (foo_struct*) some_char_ptr;
> quite_a_long_name_struct* baz = (quite_a_long_name_struct*) ( some_char_ptr
> + bar->where_is_it ); // note the second set of parentheses - casts require
> those
> // here's a "nicer" alternative:
> quite_a_long_name_struct* baz = reinterpret_cast< quite_a_long_name_struct*
>
> >( some_char_ptr + bar->where_is_it );
>
> *How haters are going to imagine it*
> #define A foo_struct
> #define B quite_a_long_name_struct
> A* bar = (A*) some_char_ptr;
> B* baz = (B*) ( some_char_ptr + bar->where_is_it );
> #undef A
> #undef B
>
> P.S. If you're going to bore me with random theory like "pointers could be
> unique identifiers uncapable of representing anything but the type" then
> please let me remind you that the second word in "computer science" means
> experiments, putting stuff into practice and watching it, trying to
> understand how it works. I've done my fair share of science and for us,
> low-level programmers, it just doesn't work in such a restricted and
> impractical way.
> P.P.S. I've been informed that accepting such a proposal would mean having
> many pages of the standard rewritten. I strongly urge you to reconsider it
> nonetheless.

snake5...@gmail.com

unread,
May 22, 2012, 4:43:52 PM5/22/12
to lang-pr...@isocpp.org
On Tuesday, May 22, 2012 11:08:33 PM UTC+3, Kodt wrote:
Explicit stating what exactly do you mean makes the program cleaner
and safer.
That's why there are static_, const_ and reinterpret_ casts in C++,
versus some versatile C cast.

What explicit stating? You mean overstating?
HeaderStruct* hs = (HeaderStruct*) buffer;
What exactly is it that makes...
HeaderStruct* hs = buffer;
...so much worse in your opinion?
Both mean the same thing, first contains redundant code that in fact makes it harder to see that "hs = buffer". How the hell could that ever be a good thing?

And before any of you criticize C for its lack of safety, try to come back to the real word, fire up a C compiler and look at what it does in the cases you mentioned. GCC doesn't let me use wrong types for my arguments.

botond...@gmail.com

unread,
Jun 2, 2012, 12:45:58 AM6/2/12
to std-pr...@isocpp.org, lang-pr...@isocpp.org

On Thursday, May 17, 2012 1:10:06 PM UTC-4, snake5...@gmail.com wrote:
And the funny thing is (well, actually there's a lot of those in every religion) that I'm not asking anyone here to use those unsafe pointers. By all means, wrap them in thousands of objects. Disable that compiler flag to make them safe (I specifically noted that this would be acceptable to me).

GCC already has a compiler flag (-fpermissive) that allows the same type-unsafe conversions in C++ code that are allowed in C code. I would imagine other compilers have similar flags. Why don't you just use that? Does it really make a difference to you whether or not the standard *mandates* the presence of such a flag?

snake5...@gmail.com

unread,
Jun 2, 2012, 2:08:28 AM6/2/12
to std-pr...@isocpp.org, lang-pr...@isocpp.org
On Saturday, June 2, 2012 7:45:58 AM UTC+3, botond...@gmail.com wrote:

GCC already has a compiler flag (-fpermissive) that allows the same type-unsafe conversions in C++ code that are allowed in C code. I would imagine other compilers have similar flags. Why don't you just use that? Does it really make a difference to you whether or not the standard *mandates* the presence of such a flag?

Yes, it's close to what I want but I don't need warnings. I don't think it's something I should be warned about. And no, not all compilers have anything like it. Haven't seen it in MSVC (which has even gone too far with applying C++'s casting rules to C code). So it really makes a difference because right now, none of the compilers really have such a flag implemented.

Martinho Fernandes

unread,
Jun 2, 2012, 8:42:28 AM6/2/12
to std-pr...@isocpp.org
On Sat, Jun 2, 2012 at 7:08 AM, <snake5...@gmail.com> wrote:
Yes, it's close to what I want but I don't need warnings. I don't think it's something I should be warned about. And no, not all compilers have anything like it. Haven't seen it in MSVC (which has even gone too far with applying C++'s casting rules to C code). So it really makes a difference because right now, none of the compilers really have such a flag implemented.

GCC lets you selectively disable warnings too: -Wno-XXX disables warning XXX.

And compiler flags are outside the scope of the standard. Requesting compiler flags is something you need to ask of your compiler vendor. If you really, really, want a standard proposal on this, you probably want to make it work some other way. 
Reply all
Reply to author
Forward
0 new messages