The fact that this headline cannot be distinguished from April Fools joke by other commenters seems to say a lot about the direction in which C++ standard committee is heading.
I remember reading about China making April Fools illegal after some major mishap where many people took a joke seriously. I was never sure if that was for real or satire.
I don’t think they are disallowed, but think most of them end up getting downvoted out of distaste (the annoying and useless April 1sts was one of the reasons I left slashdot years ago).
Obviously this one is either believed, or believed to be amusingly subtle. Either way, I agree it should be at least [Joke] flagged.
It’s not like the idea is completely crazy; pointer misuse is a big source of all kinds of problems, Rust shows how much can be done without constantly using raw pointers, and what are the C++ Core Guidelines if not an effort in exactly this direction?
I finally “got” that this is a joke when they discussed the future alternatives:
and thought, ha ha, an “assignable reference” instead of a “pointer”, that’s obviously completely different. :) What a subtle joke!
Only now I see that reference_wrapper is apparently completely real and exists since C++11. Why does this even exist? My head hurts from banging it against the desk.
The point of c/c++ in comparision to other languages is that you can do anything and having a huge toolbox for that. Pointers are excelent sledgehammer. You can be perfectly fine with not using them but c++ need to have them. The pointers are not source of the problem, the developer is. That's why languages like java are prospering, it prevent incompetent people making stupid mistakes and that is fine. But some people need and want freedom that c++ offers.
Your point may be technically accurate but the elitism of the tone completely undermines it's point because even the best of us can and do write code with errors in it. I mean just look at all the mature code out there written by experienced developers which fails fuzz testing.
I've been writing software for close on 30 years and I know damn well how easy it is to make mistakes. Even on days when I think I'm in the zone, there will be occasions when I'll go back to it and think "WTF was I thinking?" when it bombs out of the first round of automated testing.
You can have languages that prevent people making stupid mistakes and still offer full control over the hardware, that is what languages like Modula-2 and Ada offer.
Yeah, also Rust and ATS. A good systems language just needs to allow low-level and unsafe operations; nowadays the industry is warming up to the idea that such operations shouldn’t be available by default. Having to opt in with a machine-checked “unsafe” annotation means you have an explicit indication in the code of everywhere things could go wrong with type/memory safety, which means when something does go wrong, you know it must be caused by one of those unsafe regions.
The problem is that pointers almost totally violate the single responsibility principle.
Technically, the only dependencies on pointers are types of the allocation/deallocation functions which are mandated in ISO C++ even for freestanding implementations (not the case in ISO C), and their derivations (new-expressions, etc). All other sane uses of pointers should be replaced by some better alternatives when appropriate (shared_ptr, unique_ptr, observer_ptr, reference, reference_wrapper without type completeness requirement, uintptr_t, iterator, etc).
In that sense every pointer is a badly designed variant type; basically each occurrence of a pointer would likely be mostly incorrect (or not correct enough) in program semantics. I always treat that vagueness as a can of worms, so even merely replacing pointer by observer_ptr somewhere makes a big win to me. There do exist real costs like verbosity and bloating of binary size, but they have to be paid for sin of the father. The ship has sailed too far in a regretful direction; but this is not the excuse to fix it - which is one source of the problem from many developers.
1. Have a container of non-null references. As the example in your cppreference link shows, that’s convenient for efficiently providing multiple “views” of the same values.
2. Pass a value with reference semantics to a function that takes an argument by value. Mainly useful to avoid copying or reuse a function object.
3. Explicitly say “this is a reference to something I don’t own”, complementing unique_ptr’s “reference to something I own exclusively”, shared_ptr’s “reference to something I share ownership of”, and raw pointers’ “reference to something I may or may not own”.
When you use `std::bind` or `std::thread`, the arguments you pass are captured and stored by value. What if you want it to be captured as reference? You use a `std::reference_warpper` instead. Note you cannot use a pointer here because the type won't match, while `reference_wrapper` implicitly converts.
>std::reference_wrapper is a class template that wraps a reference in a copyable, assignable object. It is frequently used as a mechanism to store references inside standard containers (like std::vector) which cannot normally hold references.
>Specifically, std::reference_wrapper is a CopyConstructible and CopyAssignable wrapper around a reference [...] of type T. Instances of std::reference_wrapper are objects (they can be copied or stored in containers) but they are implicitly convertible to T&, so that they can be used as arguments with the functions that take the underlying type by reference.
Sounds pretty reasonable and useful to me. No need for over-the-top head banging :)
It is also an example of a sort of 'combinatorial pump' that inflates the language's complexity, as each new feature needs to work with every existing one. It is my guess that it is C++'s multi-paradigm flexibility that makes this both possible and necessary.
Honestly, anyone with C++ experience should understand that it's a joke just from the title. I'm honestly surprised so many people thought this could be true; even Rust has raw pointers (in unsafe mode).
Can someone with more knowledge about c++ standard comment whether this is for real or it is an April Fools joke. Wouldn't this be an enormous change and probably break the language?
It seems to be a joke, they would have serious problem with backward compatibility with "this" pointer. Also it would limit the use cases for the language, unless they would introduce something like std::raw_ptr, which to be honest would be quite funny.
In C obviously or you know, in inline assembly since it seems that it isn't going anywhere. But joking aside they could be implemented by the compilers similar to how std::function is implemented today.
There have always been library features in the C and C++ standards that can't be implemented using standard C or C++. setjmp and longjmp would be the obvious examples.
Quoted from the C++ standard: "the asm declaration is conditionally-supported; its meaning is implementation-defined". ISO C does not differ much in conformance (the asm keyword is common extension listed in annex J). There exists implementation without inline assembly support, e.g. MSVC x64. There are alternative keywords used in practice (e.g. `__asm` or `__asm__ __volatile__`). Actually the contents are not supposed to be assembly language in all cases when it is supported, as I know there exists implementation with JavaScript as the "assembly" (Cheerp). Even the implementation supports "genuine" assembly, it varies in syntax, e.g. for x86, Intel (MSVC), AT&T (Clang), or both (GCC) ?
So no, you can't expect it too much, if you have to.
I hope this is a joke: the std::weak_ptr / std::shared_ptr combo (only non-reference alternative I can think of other than std::optional) can have pretty bad performance implications due to ref-counting atomics in multi-threaded scenarios...
For the use-case of optional pointers that don't have any ownership (and can possibly be updated mid-lifetime) and have a guaranteed external lifetime, what's the alternative?
Are there any other ways of doing this that are guaranteed to have no performance (time or memory) overhead in modern C++ (relying on by-value move semantics isn't ideal) ?
Also, what about std:atomic (CAS) raw pointers - for high-performance / lockless stuff, they can be critical...
For the use-case of optional pointers that don't have any ownership (and can possibly be updated mid-lifetime) and have a guaranteed external lifetime
Those three things seem like a pretty rare co-occurrence, if something has no ownership how can it have guaranteed external lifetime without being reference counted? I guess it's possible but in any scenario I come up with reference counting seems an easier way to do it.
There is nothing in C++ 11 and later that is forced on you. Everything that was added is optional. For personal projects I depend on some alternate implementations for things that are now in the STL because these not complete enough for my needs.
I did not wrote these things for fun. I had a real need for each one. The STL is fine for the average case, but it is also limited. I hit these limitations.
C++17 removed exception specifications from the language, and parts of the standard library, including std::auto_ptr and a lot of the <functional> header.
>this accelerated process of mutating the language
Oh we can't be talking about the same language x) C++ moves fast? They took until 2017 to remove trigraphs for crying out loud! Absolutely nothing in C++>=11 breaks anything in the language.
Fair point. My feeling has been that the committee is trying to make the language safe (as is now the fashion) by adding increasingly more features, with the intention of deprecating old workflows aggressively.
But the language complexity is now so significant that a new dev would take years to fully understand both "old" C++ and new C++, and how to make them work well together
I guess a serious point is that modern C++ does "deprecate" raw pointers in the sense that their use is discouraged outside of interfacing with external libraries or old C++ code.
But that's more the realm of linters than compiler warnings.
so tldr, the C haters have won in the process of rubyizing C++ for webdevs who literally could not care less about a language that they have absolutely no use for...
Obvious joke is obvious. I looked at the date immediately after reading the title. Now, if that was to be discussed for C++23, that could indeed be plausible... yet still unlikely.
I've never done any real development with a language that uses pointers. So noob question: why would one use a pointer over passing a variable? (those are the two flavors right?)
When passing a pointer, if you want the resulting state of the variable, the function doesn't need to return a value. Also if the variable is a large object, then passing just a pointer to it saves time spent copying the object.
There's absolutely no reason to use pointers, unmentioned detail is that c++20 will bundle v8's garbage collector in the runtime to support this removal.
In other news: Bjarne Stroustrup hast been fired by the C++ language committee, as one data member declared "we are sick and tired of this backard compatibility with C mantra, we all want to party like Rust!". Today everything is possible...
You can follow the links to more details, which goes to a different blog post. Each has another blog post as a source, and eventually comes back in a circle to the original one.
It's an April fool's day joke in the best tradition: a parody almost indistinguishable from truth. C++ has jumped the shark.
Prima facie C was created as a portable assembly language that very nearly reflected the underlying hardware. Then C++ added new abstraction mechanisms on top of C, that were at first totally orthogonal: just classes and templates. One could still use all of C to get at the raw machine (raw pointers and peeking/poking). Then as abstraction envy grew to overcome C++, as it does every active language in time, C++ drifted farther and farther from its system-y roots. Fine.
But in my day job, the only real reason to use C++ is because it's the only realistic choice as a systems language. I need to peek and poke memory, jump to raw machine code I've generated at runtime. This doesn't make me better or worse, it's just my use case (a virtual machine). As C++ becomes less and less capable of doing these low-level unsafe things (because too many people caused too much damage attempting this), and adds more ceremony to the old ways of peeking and poking memory, it becomes less useful to me. Who is it useful for?
I'd argue that C++ has drifted off into some fantasy world where it believes it's a beautiful language full of nice, solid abstractions. But IMO it isn't--probably can't be--as all the abstractions break down, leaving us in the lurch, with neither good systems programming support nor good application-level abstraction.
> I'd argue that C++ has drifted off into some fantasy world where it believes it's a beautiful language full of nice, solid abstractions. But IMO it isn't--probably can't be--as all the abstractions break down, leaving us in the lurch, with neither good systems programming support nor good application-level abstraction.
I’m not sure I’d say all the abstractions break down. If you and your team can agree on a subset of C++ features and patterns that work really well, you really can have some nice, clean code that yields both effective abstractions and good system-level results.
The problem with C++ is that it’s effectively a giant pile of tools, that keeps getting new tools dumped on the pile every few years —- some of which meant to “replace” older tools, yet rarely remove any tools (for fear of breaking backwards compatibility). So the pile keeps getting bigger and bigger, until it some day collapses under its own weight of complexity (maybe).
Skilled craftspeople can still use these tools to great effect, but there is at least an organizational overhead and danger from how cluttered and huge the set of tools is: every person or team may use a different subset of tools due to differing preference, not knowing about all the tools, not using some tools “properly”, using the “bad” tools, etc. etc.
To strain the analogy a bit further - that's the thing about going to a hardware store. Bringing everything home is not really useful, so you'll have to be educated on which tools are needed for your job. And possibly all you really wanted was a hammer, and that's perfectly fine too.
I don’t know if the joke is about C++ or the committee, which has approved many things that don’t feel like C++ to me (i.e., I strongly suspect that some committee members aren’t big fans of the language).
I like what E. W. Dijkstra had to say in "The Humble Programmer":
> Finally, although the subject is not a pleasant one, I must mention C++, a programming language for which the defining documentation is of a frightening size and complexity. Using C++ must be like flying a plane with 7000 buttons, switches and handles to manipulate in the cockpit. I absolutely fail to see how we can keep our growing programs firmly within our intellectual grip when by its sheer baroqueness the programming language —our basic tool, mind you!— already escapes our intellectual control. And if I have to describe the influence C++ can have on its users, the closest metaphor that comes to my mind is that of a drug. I remember from a symposium on higher level programming language a lecture given in defense of C++ by a man who described himself as one of its devoted users. But within a one-hour lecture in praise of C++. he managed to ask for the addition of about fifty new “features”, little supposing that the main source of his problems could very well be that it contained already far too many “features”. The speaker displayed all the depressing symptoms of addiction, reduced as he was to the state of mental stagnation in which he could only ask for more, more, more... When FORTRAN has been called an infantile disorder, full C++, with its growth characteristics of a dangerous tumor, could turn out to be a fatal disease.
April fool's. He actually said that about PL/1 [1].
> Then C++ added new abstraction mechanisms on top of C, that were at first totally orthogonal: just classes and templates.
Not quite. Classes are based on struct types in C. Templates are based on classes, function types, and more.
> As C++ becomes less and less capable of doing these low-level unsafe things (because too many people caused too much damage attempting this), and adds more ceremony to the old ways of peeking and poking memory, it becomes less useful to me.
This is not the truth. It is just never supported in a portable way. And there is no other choice. ISO C is also always lack of that capability (if not more restricted). Nevertheless, you can still rely on the usefulness provided by implementations, as-is.
Having started using the Internet in the 90's, and thus still remembering Geocities-era websites, I loved that they did this as a webring (https://en.wikipedia.org/wiki/Webring): each blog post has a link to the next one, making a singly-linked circular list.
On a more serious note, raw pointers can be seen as practically deprecated in C++ since its inception (at least inside code that is not considered library or low-level).
83 comments
[ 3.0 ms ] story [ 25.4 ms ] thread> Additionally, I refer to the post C++ Will no Longer Have Pointers by Fluent C++
Following the trail of references just loops around a half dozen April 1st posts.
With that, and nothing on the drafts [0], that I can see, I'm leaning towards joke.
[0] https://github.com/cplusplus/draft
FYI, here was one of Chinese translation of the article, but the contents was just deleted 10 minutes ago:
https://www.oschina.net/news/94805/deprecating-pointers
Obviously this one is either believed, or believed to be amusingly subtle. Either way, I agree it should be at least [Joke] flagged.
I finally “got” that this is a joke when they discussed the future alternatives:
> For copyable and assignable references you can use std::reference_wrapper. (http://en.cppreference.com/w/cpp/utility/functional/referenc...)
and thought, ha ha, an “assignable reference” instead of a “pointer”, that’s obviously completely different. :) What a subtle joke!
Only now I see that reference_wrapper is apparently completely real and exists since C++11. Why does this even exist? My head hurts from banging it against the desk.
That still crazy though :)
The point of c/c++ in comparision to other languages is that you can do anything and having a huge toolbox for that. Pointers are excelent sledgehammer. You can be perfectly fine with not using them but c++ need to have them. The pointers are not source of the problem, the developer is. That's why languages like java are prospering, it prevent incompetent people making stupid mistakes and that is fine. But some people need and want freedom that c++ offers.
You need plenty of tests and valgrind.
Its dangerous for most programmers to be cavalier with owning raw pointers. If we aren't we'll get another Java.
I've been writing software for close on 30 years and I know damn well how easy it is to make mistakes. Even on days when I think I'm in the zone, there will be occasions when I'll go back to it and think "WTF was I thinking?" when it bombs out of the first round of automated testing.
Technically, the only dependencies on pointers are types of the allocation/deallocation functions which are mandated in ISO C++ even for freestanding implementations (not the case in ISO C), and their derivations (new-expressions, etc). All other sane uses of pointers should be replaced by some better alternatives when appropriate (shared_ptr, unique_ptr, observer_ptr, reference, reference_wrapper without type completeness requirement, uintptr_t, iterator, etc).
In that sense every pointer is a badly designed variant type; basically each occurrence of a pointer would likely be mostly incorrect (or not correct enough) in program semantics. I always treat that vagueness as a can of worms, so even merely replacing pointer by observer_ptr somewhere makes a big win to me. There do exist real costs like verbosity and bloating of binary size, but they have to be paid for sin of the father. The ship has sailed too far in a regretful direction; but this is not the excuse to fix it - which is one source of the problem from many developers.
1. Have a container of non-null references. As the example in your cppreference link shows, that’s convenient for efficiently providing multiple “views” of the same values.
2. Pass a value with reference semantics to a function that takes an argument by value. Mainly useful to avoid copying or reuse a function object.
3. Explicitly say “this is a reference to something I don’t own”, complementing unique_ptr’s “reference to something I own exclusively”, shared_ptr’s “reference to something I share ownership of”, and raw pointers’ “reference to something I may or may not own”.
When you use `std::bind` or `std::thread`, the arguments you pass are captured and stored by value. What if you want it to be captured as reference? You use a `std::reference_warpper` instead. Note you cannot use a pointer here because the type won't match, while `reference_wrapper` implicitly converts.
>std::reference_wrapper is a class template that wraps a reference in a copyable, assignable object. It is frequently used as a mechanism to store references inside standard containers (like std::vector) which cannot normally hold references.
>Specifically, std::reference_wrapper is a CopyConstructible and CopyAssignable wrapper around a reference [...] of type T. Instances of std::reference_wrapper are objects (they can be copied or stored in containers) but they are implicitly convertible to T&, so that they can be used as arguments with the functions that take the underlying type by reference.
Sounds pretty reasonable and useful to me. No need for over-the-top head banging :)
Meaning ANSI C does not refer at all to inline Assembly, from its point of view it does not exist.
ANSI C++ on other hand, specifies the asm keyword and that it should enable a compiler specific way to write inline Assembly.
But yeah, neither of them actually specifies how it should look.
Quoted from the C++ standard: "the asm declaration is conditionally-supported; its meaning is implementation-defined". ISO C does not differ much in conformance (the asm keyword is common extension listed in annex J). There exists implementation without inline assembly support, e.g. MSVC x64. There are alternative keywords used in practice (e.g. `__asm` or `__asm__ __volatile__`). Actually the contents are not supposed to be assembly language in all cases when it is supported, as I know there exists implementation with JavaScript as the "assembly" (Cheerp). Even the implementation supports "genuine" assembly, it varies in syntax, e.g. for x86, Intel (MSVC), AT&T (Clang), or both (GCC) ?
So no, you can't expect it too much, if you have to.
For the use-case of optional pointers that don't have any ownership (and can possibly be updated mid-lifetime) and have a guaranteed external lifetime, what's the alternative?
Are there any other ways of doing this that are guaranteed to have no performance (time or memory) overhead in modern C++ (relying on by-value move semantics isn't ideal) ?
Also, what about std:atomic (CAS) raw pointers - for high-performance / lockless stuff, they can be critical...
Those three things seem like a pretty rare co-occurrence, if something has no ownership how can it have guaranteed external lifetime without being reference counted? I guess it's possible but in any scenario I come up with reference counting seems an easier way to do it.
It is very much in keeping with the current direction of C++, which appears to be:
"Oh no, C++ cannot keep pace with modern systems languages, let's repair it by whatever means possible"
Their heart is in the right place, but perhaps this accelerated process of mutating the language will ultimately be what kills it.
Personally, after having deep expertise in C++(11/14) I jumped ship to Go and will _never_ look back...
https://isocpp.org/files/papers/p0636r0.html
Oh we can't be talking about the same language x) C++ moves fast? They took until 2017 to remove trigraphs for crying out loud! Absolutely nothing in C++>=11 breaks anything in the language.
But the language complexity is now so significant that a new dev would take years to fully understand both "old" C++ and new C++, and how to make them work well together
But that's more the realm of linters than compiler warnings.
I'm glad I decided against moving to C++
Too obvious.
Is this actually a joke ?
This is most definitely an April Fool's joke.
But then that post also has a link to a source, which is another blog post, which links to another, which via a few more links back to this one.
We have citogenesis[1] in actual action.
[1] https://xkcd.com/978/
Prima facie C was created as a portable assembly language that very nearly reflected the underlying hardware. Then C++ added new abstraction mechanisms on top of C, that were at first totally orthogonal: just classes and templates. One could still use all of C to get at the raw machine (raw pointers and peeking/poking). Then as abstraction envy grew to overcome C++, as it does every active language in time, C++ drifted farther and farther from its system-y roots. Fine.
But in my day job, the only real reason to use C++ is because it's the only realistic choice as a systems language. I need to peek and poke memory, jump to raw machine code I've generated at runtime. This doesn't make me better or worse, it's just my use case (a virtual machine). As C++ becomes less and less capable of doing these low-level unsafe things (because too many people caused too much damage attempting this), and adds more ceremony to the old ways of peeking and poking memory, it becomes less useful to me. Who is it useful for?
I'd argue that C++ has drifted off into some fantasy world where it believes it's a beautiful language full of nice, solid abstractions. But IMO it isn't--probably can't be--as all the abstractions break down, leaving us in the lurch, with neither good systems programming support nor good application-level abstraction.
I’m not sure I’d say all the abstractions break down. If you and your team can agree on a subset of C++ features and patterns that work really well, you really can have some nice, clean code that yields both effective abstractions and good system-level results.
The problem with C++ is that it’s effectively a giant pile of tools, that keeps getting new tools dumped on the pile every few years —- some of which meant to “replace” older tools, yet rarely remove any tools (for fear of breaking backwards compatibility). So the pile keeps getting bigger and bigger, until it some day collapses under its own weight of complexity (maybe).
Skilled craftspeople can still use these tools to great effect, but there is at least an organizational overhead and danger from how cluttered and huge the set of tools is: every person or team may use a different subset of tools due to differing preference, not knowing about all the tools, not using some tools “properly”, using the “bad” tools, etc. etc.
That said, I fell for this joke.
I like what E. W. Dijkstra had to say in "The Humble Programmer":
> Finally, although the subject is not a pleasant one, I must mention C++, a programming language for which the defining documentation is of a frightening size and complexity. Using C++ must be like flying a plane with 7000 buttons, switches and handles to manipulate in the cockpit. I absolutely fail to see how we can keep our growing programs firmly within our intellectual grip when by its sheer baroqueness the programming language —our basic tool, mind you!— already escapes our intellectual control. And if I have to describe the influence C++ can have on its users, the closest metaphor that comes to my mind is that of a drug. I remember from a symposium on higher level programming language a lecture given in defense of C++ by a man who described himself as one of its devoted users. But within a one-hour lecture in praise of C++. he managed to ask for the addition of about fifty new “features”, little supposing that the main source of his problems could very well be that it contained already far too many “features”. The speaker displayed all the depressing symptoms of addiction, reduced as he was to the state of mental stagnation in which he could only ask for more, more, more... When FORTRAN has been called an infantile disorder, full C++, with its growth characteristics of a dangerous tumor, could turn out to be a fatal disease.
April fool's. He actually said that about PL/1 [1].
[1] https://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340...
Not quite. Classes are based on struct types in C. Templates are based on classes, function types, and more.
> As C++ becomes less and less capable of doing these low-level unsafe things (because too many people caused too much damage attempting this), and adds more ceremony to the old ways of peeking and poking memory, it becomes less useful to me.
This is not the truth. It is just never supported in a portable way. And there is no other choice. ISO C is also always lack of that capability (if not more restricted). Nevertheless, you can still rely on the usefulness provided by implementations, as-is.
Starting with this one, we have:
- http://www.bfilipek.com/2018/04/deprecating-pointers.html
- http://www.modernescpp.com/index.php/no-new-new
- https://www.fluentcpp.com/2018/04/01/cpp-will-no-longer-have...
- https://blog.tartanllama.xyz/no-pointers/
- https://arne-mertz.de/2018/04/raw-pointers-are-gone/
And it circles back to this one.