Was strstream ever part of the standard? - c++

Recently I've skimmed through n3376 and came across an interesting section in Annex D: [depr.ios.members]. It mentions the "old" IO-classes strstreambuf, istrstream, ... as deprecated.
Personally I haven't used any of these for any serious program (think I once had to use them in an assignment, but after that i stayed with <sstream>).
From what I know these classes were pre-standard, but were they ever part of any standard? If not, I don't quite understand why there are even mentioned in the standard...

Yes, they always were (since 1998) and are part of the standard, but they are deprecated (and always have been, since 1998).
The natural question that follows is: why were they added as deprecated? I can only speculate here, but there is no alternative where you can manage your own buffer, and you can not access the string of stringstream directly, so this template is without a good alternative. The committee will surely be open for a new proposal to fill this gap (that is, control the buffer), but undeprecating strstream is likely a no-no.

Related

Is there a reason why implementations allow instantiation of std::complex with unsupported types

edit note:
originally question said illegal where now it says unspecified.
Thanks to video comment section of Jason Turner video recently I learned that std::complex<int> is unspecified.
But all(AFAIK) implementations seem to happily compile
std::complex<int>
But some functions like std::abs() are broken for std::complex<int>, so it's not actually usable in those mainstream implementaitons.
I wonder if there is some reason why detection for "bad" types was never implemented. I know that std lib implementations need to work with older standards so they can not just stuck std::floating_point concept everywhere, but even before C++20 we had ways to constrain templates.
In other words: is this just "would be nice, but we dont have time" issue, or is there some compatibility reason to keep this compiling.
Only thing I can think of is that some people are using std::complex and std lib "manufacturers" do not want to obviously break their already broken code.
It is actually not illegal, it is unspecified;
From [complex.numbers]/2
The effect of instantiating the template complex for any type other than float, double, or long double is
unspecified.
Unspecified, from [defns.unspecified] means
unspecified behavior
behavior, for a well-formed program construct and correct data, that depends on the implementation
[Note 1 to entry: The implementation is not required to document which behavior occurs. The range of
possible behaviors is usually delineated by this document. —end note]
(references from N4860 (C++20 draft)
Is there a reason why implementations allow instantiation of std::complex with unsupported types?
I wonder if there is some reason why detection for "bad" types was never implemented.
Both unspecified behavior (what you are describing) and undefined behavior are valuable in that they allow for new behavior in future standards.
If a future C++ standard were to implement a long long double or decimal type, then std::complex could also be revised to support it.
It it were someday decided that std::complex<int> has great importance, a future standard could promise to implement it.
If, instead, the standard had promised to "detect 'bad' types", these revisions could not happen without putting C++ standards in conflict.

Why are std::source_location's getters not marked as [[nodiscard]]? [duplicate]

I've recently read about [[nodiscard]] in C++17, and as far as I understand it's a new feature (design by contract?) which forces you to use the return value. This makes sense for controversial functions like std::launder (nodiscard since C++20), but I wonder why std::move isn't defined like so in C++17/20. Do you know a good reason or is it because C++20 isn't finalised yet?
The MSVC standard library team went ahead and added several thousand instances of [[nodiscard]] since VS 2017 15.6, and have reported wild success with it (both in terms of finding lots of bugs and generating no user complaints). The criteria they described were approximately:
Pure observers, e.g. vector::size(), vector::empty, and even std::count_if()
Things that acquire raw resources, e.g. allocate()
Functions where discarding the return value is extremely likely to lead to incorrect code, e.g. std::remove()
MSVC does mark both std::move() and std::forward() as [[nodiscard]] following these criteria.
While it's not officially annotated as such in the standard, it seems to provide clear user benefit and it's more a question of crafting such a paper to mark all the right things [[nodiscard]] (again, several thousand instances from MSVC) and apply them -- it's not complex work per se, but the volume is large. In the meantime, maybe prod your favorite standard library vendor and ask them to [[nodiscard]] lots of stuff?
AFAIK P0600R1 is the only proposal for adding [[nodiscard]] to the standard library that was applied to C++20. From that paper:
We suggest a conservative approach:
[...]
It should not be added when:
[...]
not using the return value makes no sense but doesn’t hurt and is usually not an error
[...]
So, [[nodiscard]] should not signal bad code if this
[...]
doesn’t hurt and probably no state change was meant that doesn’t happen
So the reason is that the standard library uses a conservative approach and a more aggresive one is not yet proposed.

Why is std::move not [[nodiscard]] in C++20?

I've recently read about [[nodiscard]] in C++17, and as far as I understand it's a new feature (design by contract?) which forces you to use the return value. This makes sense for controversial functions like std::launder (nodiscard since C++20), but I wonder why std::move isn't defined like so in C++17/20. Do you know a good reason or is it because C++20 isn't finalised yet?
The MSVC standard library team went ahead and added several thousand instances of [[nodiscard]] since VS 2017 15.6, and have reported wild success with it (both in terms of finding lots of bugs and generating no user complaints). The criteria they described were approximately:
Pure observers, e.g. vector::size(), vector::empty, and even std::count_if()
Things that acquire raw resources, e.g. allocate()
Functions where discarding the return value is extremely likely to lead to incorrect code, e.g. std::remove()
MSVC does mark both std::move() and std::forward() as [[nodiscard]] following these criteria.
While it's not officially annotated as such in the standard, it seems to provide clear user benefit and it's more a question of crafting such a paper to mark all the right things [[nodiscard]] (again, several thousand instances from MSVC) and apply them -- it's not complex work per se, but the volume is large. In the meantime, maybe prod your favorite standard library vendor and ask them to [[nodiscard]] lots of stuff?
AFAIK P0600R1 is the only proposal for adding [[nodiscard]] to the standard library that was applied to C++20. From that paper:
We suggest a conservative approach:
[...]
It should not be added when:
[...]
not using the return value makes no sense but doesn’t hurt and is usually not an error
[...]
So, [[nodiscard]] should not signal bad code if this
[...]
doesn’t hurt and probably no state change was meant that doesn’t happen
So the reason is that the standard library uses a conservative approach and a more aggresive one is not yet proposed.

What is the equivalent standard function of the "AfxIsValidAddress" function?

I was using an MFC-project, that shall be proted in a platform-independent environment, using std-function instead of MFC/AFX.
For example: instead CString the std::string, instead CMutex the std::mutex will be used.
What is the platform-independet, C++11 std::-equivalent of the MFC function "AfxIsValidAddress"?
There is not something similar to AfxIsValidAddress() in the standard library and it appears that the function doesn't actually do that much validation anyway.
See AfxIsValidAddress (and Others) Don’t Work as Advertised which says the function ends up just doing a check against NULL. It also has this to say about the family of valid address check functions:
There are several Win32 API similar in functionality: IsBadWritePtr,
IsBadHugeWritePtr, IsBadReadPtr, IsBadHugeReadPtr, IsBadCodePtr,
IsBadStringPtr. It has been known since at least 2004 that these
functions are broken beyond repair and should never be used. The
almighty Raymond Chen and Larry Osterman both discuss the reasons in
detail, so just a short rehash: IsBad*Ptr all work by accessing the
tested address and catching any thrown exceptions. Problem is that a
certain few of these access violations (namely, those on stack guard
pages) should never be caught – the OS uses them to properly enlarge
thread stacks.
I think it is better to just follow standard C++ procedures to check that a pointer is not a nullptr or better yet to limit the use of pointers as much as possible.

Why do streams still convert to pointers in C++11?

The canonical way to read lines from a text file is:
std::fstream fs("/tmp/myfile.txt");
std::string line;
while (std::getline(line, fs)) {
doThingsWith(line);
}
(no, it is not while (!fs.eof()) { getline(line, fs); doThingsWith(line); }!)
This works beacuse std::getline returns the stream argument by reference, and because:
in C++03, streams convert to void*, via an operator void*() const in std::basic_ios, evaluating to the null pointer value when the fail error flag is set;
see [C++03: 27.4.4] & [C++03: 27.4.4.3/1]
in C++11, streams convert to bool, via an explicit operator bool() const in std::basic_ios, evaluating to false when the fail error flag is set
see [C++11: 27.5.5.1] & [C++11: 27.5.5.4/1]
In C++03 this mechanism means the following is possible:
std::cout << std::cout;
It correctly results in some arbitrary pointer value being output to the standard out stream.
However, despite operator void*() const having been removed in C++11, this also compiles and runs for me in GCC 4.7.0 in C++11 mode.
How is this still possible in C++11? Is there some other mechanism at work that I'm unaware of? Or is it simply an implementation "oddity"?
I'm reasonably certain this is not allowed/can't happen in a conforming implementation of C++11.
The problem, of course, is that right now, most implementations are working on conforming, but aren't there completely yet. At a guess, for many vendors, this particular update is a fairly low priority. It improves error checking, but does little (or nothing) to enable new techniques, add new features, improve run-time efficiency, etc. This lets the compiler catch the error you've cited (some_stream << some_other_stream) but doesn't really make a whole lot of difference otherwise.
If I were in charge of updating a standard library for C++11, I think this would be a fairly low priority. There are other changes that are probably as easy (if not easier) to incorporate, and likely to make a much bigger difference to most programmers.
To use one of the examples you gave, if I were in charge of updating the VC++ standard library to take advantage of the compiler features added in the November CTP, my top priority would probably be to add constructors to the standard container types to accept initialization_lists. These are fairly easy to add (I'd guess one person could probably add and test them in under a week) and make quite an obvious, visible difference in what a programmer can do.
As late as GCC 4.6.2, the libstdc++ code for basic_ios is evidently still C++03-like.
I'd simply put this down to "they haven't gotten around to it yet".
By contrast, the libc++ (LLVM's stdlib implementation) trunk already uses operator bool().
This was a missed mini-feature buried in a pre-existing header. There are probably lots of missing error of omission and commission in pre-2011 components.
Really, if anyone comes up with things like this in gcc then it would do a world of good to go to Bugzilla and make a bug report. It may be a low priority bug but if you start a paper trail
I'll go out on a limb and extend this idea to all the other C++ compilers: clang, Visual Studio,etc.
This will make C++ a better place.
P.S. I entered a bug in Bugzilla.