Thursday, December 26, 2019

Digest for comp.lang.c++@googlegroups.com - 17 updates in 3 topics

boltar@nowhere.org: Dec 26 09:46AM

On Wed, 25 Dec 2019 00:30:46 +0200
 
>"If an optional<T> contains a value, the value is guaranteed to be
>allocated as part of the optional object footprint, i.e. no dynamic
>memory allocation ever takes place. Thus, an optional object models an
 
Of course dynamic memory allocation takes place - its not going to be on
the stack if its in a container is it? It might be implicit rather than
explicit but its still dynamic and as such is subject to where the allocator
puts it.
Paavo Helde <myfirstname@osa.pri.ee>: Dec 26 04:38PM +0200

>> memory allocation ever takes place. Thus, an optional object models an
 
> Of course dynamic memory allocation takes place - its not going to be on
> the stack if its in a container is it?
 
If a std::optional is stored as an automatic variable then of course it
is allocated at stack. Where else? And this includes also its contained
value, as there is absolutely no reason to allocate it dynamically.
 
> It might be implicit rather than
> explicit but its still dynamic and as such is subject to where the allocator
> puts it.
 
Fortunately programming is a concrete field and one can answer concrete
enough questions factually, no need to decide anything be shouting
louder than others. Here is a little program to find out where a class A
value contained in a std::optional is allocated. You can run it with
your favorite C++ compiler if you don't trust mine.
 
#include <optional>
#include <iostream>
 
class A {
public:
A(int a) : a_(a) {}
void foo() const {
std::cout << "Hello, I'm an A at address: " << this << "\n";
}
private:
int a_;
};
 
int main() {
int x = 1;
std::optional opt1 = A(42);
int y = 2;
 
std::cout << "Stack variable x is at address: " << &x << "\n";
std::cout << "Stack variable y is at address: " << &y << "\n";
opt1->foo();
}
 
Output:
Stack variable x is at address: 00000000002CF874
Stack variable y is at address: 00000000002CF8B4
Hello, I'm an A at address: 00000000002CF898
 
So, what's next? Will you claim that x and y are not stack variables? Or
will you deny 0x2CF898 lies between 0x2CF874 and 0x2CF8B4? Or will you
say that the dynamic allocator somehow is able to use memory space
between two stack variables for a dynamic allocation? Or will you say
that all existing implementations of std::optional are wrong in storing
the value on stack and should use the more expensive dynamic allocation
instead?
 
Note that if the value contained in a std::optional would be indeed
allocated dynamically, there would be no need for std::optional in the
first place as then one would have a (raw or smart) pointer pointing to
this dynamically allocated value, and one could just use the special
nullptr value for indicating the "missing value" condition.
boltar@nowhere.org: Dec 26 05:33PM

On Thu, 26 Dec 2019 16:38:12 +0200
 
>If a std::optional is stored as an automatic variable then of course it
>is allocated at stack. Where else? And this includes also its contained
>value, as there is absolutely no reason to allocate it dynamically.
 
For some noddy function. If however you have a container that is added to
based on some operation in a loop its hardly going to be allocated on the
stack is it? (Unless you use an allocator that uses alloca() or similar. And
good luck with that).
 
>value contained in a std::optional is allocated. You can run it with
>your favorite C++ compiler if you don't trust mine.
 
A contrived example. Now allocate optionals containing objects in a loop.
Paavo Helde <myfirstname@osa.pri.ee>: Dec 26 07:52PM +0200

> based on some operation in a loop its hardly going to be allocated on the
> stack is it? (Unless you use an allocator that uses alloca() or similar. And
> good luck with that).
 
True for some kind of containers, but std::optional is not one of those.
 
 
>> value contained in a std::optional is allocated. You can run it with
>> your favorite C++ compiler if you don't trust mine.
 
> A contrived example. Now allocate optionals containing objects in a loop.
 
You cannot refute direct evidence just be calling it "contrived" (which
it isn't). And loops have nothing to do with how std::optional works.
Mr Flibble <flibble@i42.removethisbit.co.uk>: Dec 26 06:30PM


>> value contained in a std::optional is allocated. You can run it with
>> your favorite C++ compiler if you don't trust mine.
 
> A contrived example. Now allocate optionals containing objects in a loop.
 
#include <optional>
#include <iostream>
 
int main()
{
std::optional<int> o = 42;
std::cout << "address of optional on stack: " << std::hex << &o
<< std::endl;
std::cout << "address of optional contained value: " <<
std::hex << &*o << std::endl;
}
 
Output:
address of optional on stack: 0x7ffc35b03890
address of optional contained value: 0x7ffc35b03890
 
Now will you please fuck off you deliberately obtuse idiot.
 
/Flibble
 
--
"You won't burn in hell. But be nice anyway." – Ricky Gervais
"I see Atheists are fighting and killing each other again, over who
doesn't believe in any God the most. Oh, no..wait.. that never happens."
– Ricky Gervais
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates
a world that is so full of injustice and pain. That's what I would say."
Daniel <danielaparker@gmail.com>: Dec 26 10:38AM -0800

> the stack if its in a container is it? It might be implicit rather than
> explicit but its still dynamic and as such is subject to where the allocator
> puts it.
 
A typical implementation of optional<T> uses data storage something like
 
union {
char dummy;
std::remove_const_t<T> value;
};
bool has_value;
 
and uses placement new to initialize value if defined. There's no dynamic
allocation happening here, for example,
 
std::optional<std::string> o1{}; // does not contain a value
std::optional<std::string> o2 = "Hello"; // contains a small string value
 
Best regards,
Daniel
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Dec 26 10:54AM -0800

> On 26.12.2019 11:46, boltar@nowhere.org wrote:
[...]
> it is allocated at stack. Where else? And this includes also its
> contained value, as there is absolutely no reason to allocate it
> dynamically.
 
[...]
 
> shouting louder than others. Here is a little program to find out
> where a class A value contained in a std::optional is allocated. You
> can run it with your favorite C++ compiler if you don't trust mine.
 
[...]
 
Your program only demonstrates that the T object is allocated
within the optional<T> object *for the implementation you used*.
(Defining an optional<T> type with a large parameter type T and
printing its size would be a simpler way to demonstrate that.)
I can easily imagine that a different implementation might store
the T object outside the optional<T> object, saving space when it's
not present.
 
What *does* prove that the T object is stored within the optional<T>
object is that the standard says it must be. C++17 23.6.3
[optional.optional] paragraph 1:
 
Any instance of optional<T> at any given time either contains
a value or does not contain a value. When an instance of
optional<T> *contains a value*, it means that an object of
type T, referred to as the optional object's contained
value, is allocated within the storage of the optional
object. Implementations are not permitted to use additional
storage, such as dynamic memory, to allocate its contained value.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
[Note updated email address]
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Paavo Helde <myfirstname@osa.pri.ee>: Dec 26 10:50PM +0200

On 26.12.2019 20:54, Keith Thompson wrote:
> What *does* prove that the T object is stored within the optional<T>
> object is that the standard says it must be. C++17 23.6.3
> [optional.optional] paragraph 1:
 
You are right, but as it appears "boltar" is not easily swayed by mere
words, I was trying something more concrete. Probably in vain...
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 04:47PM +0100

Why, with the below code, do I get this result:
 
> echo no no no not ever | a
ever 1
no 1
not 1
 
I had expected a count of three for "no".
 
Also, how the feck does the commented line cause a Most Vexing Parse? I
was sure that by having a constructor call with `cin` as argument there,
i.e. a value argument, there could be no vexing parse. But g++ just
doesn't like it and then misleadingly complains about something later in
the code, using an avalanche of idiot diagnostics so as to ensure one
would waste time on it.
 
 
-------------------------------------------------
// Read a file of text, determine the n most frequently used words, and
print out a sorted
// list of those words along with their frequencies.
//
//
https://medium.com/@vgasparyan1995/a-little-bit-of-code-c-20-ranges-c6a6f7eae401
 
// Assuming
// * ASCII lowercase text
// * No punctuation.
 
#include <iterator>
#include <iostream>
#include <string>
#include <unordered_set>
 
template< class Key > using Multiset_ = std::unordered_set<Key>;
 
auto main()
-> int
{
using std::cin, std::cout, std::endl, std::string;
using Iit = std::istream_iterator<string>;
const Iit end = Iit();
Multiset_<string> words( Iit( cin ), (Iit()) ); // OK
//Multiset_<string> words( Iit( cin ), Iit() ); //! Most
vexing parse?
for( const string& s: words ) {
cout << s << ' ' << words.count( s ) << endl;
}
}
-------------------------------------------------
 
 
- Alf (possibly in superstupido-mode, for various reasons)
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 04:51PM +0100

On 26.12.2019 16:47, Alf P. Steinbach wrote:
> no 1
> not 1
 
> I had expected a count of three for "no".
 
Oh, just a typo. I had forgot to writ "multi" in std::unordered_multiset.
 
 
> doesn't like it and then misleadingly complains about something later in
> the code, using an avalanche of idiot diagnostics so as to ensure one
> would waste time on it.
 
But this? I can't get my head around it. Right now.
 
 
Bo Persson <bo@bo-persson.se>: Dec 26 04:55PM +0100

On 2019-12-26 at 16:47, Alf P. Steinbach wrote:
> }
> -------------------------------------------------
 
> - Alf (possibly in superstupido-mode, for various reasons)
 
Some more coffee needed, possibly?
 
Multiset_ sounds like a multiset, but it really is not if we read the
using-line carefully. :-)
 
And for the most vexing parse - cin is a value, but it *could* also be
the name of a parameter for a (hypothetical) words function. So parsing
a declaration wins!
 
 
Bo Persson
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 12:49AM +0100

On 25.12.2019 23:28, Pavel wrote:
 
> I make 2 conclusions:
 
> A. some identifiers (in particular those starting with _) shall not be
> used by otherwise than by C++ implementation
 
The parenthetical remark does not follow from anything.
 
 
> B. If an identifier starting with _ not followed by an uppercase letter
> is used by C++ implementation, it should be used as a name in the global
> namespace.
 
... or namespace `std`.
 
 
> clause Alf referred to in his recollection of the Standard, namely:
 
> Identifiers starting with `_` are reserved in the global namespace.
 
> What I am missing?
 
Rather, the question is where you get these ideas.
 
 
- Alf
Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo>: Dec 25 07:54PM -0500

Alf P. Steinbach wrote:
 
>> A. some identifiers (in particular those starting with _) shall not be
>> used by otherwise than by C++ implementation
 
> The parenthetical remark does not follow from anything.
except it follows from 3.2 cited right above
>> is used by C++ implementation, it should be used as a name in the global
>> namespace.
 
> ... or namespace `std`.
*that* is what does not seem to follow from anything.
 
>> Identifiers starting with `_` are reserved in the global namespace.
 
>> What I am  missing?
 
> Rather, the question is where you get these ideas.
Oh, the answer to this one is simple: boolean logic applied to A and B
above.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 03:53AM +0100

On 26.12.2019 01:54, Pavel wrote:
 
>> Rather, the question is where you get these ideas.
> Oh, the answer to this one is simple: boolean logic applied to A and B
> above.
 
This reminds me strongly of the tortoise's denial arguments in
Hofstadter's "Gödel, Escher, Bach: An Eternal Golden Braid".
 
I recommend that book.
 
- Alf
Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo>: Dec 25 10:32PM -0500

Alf P. Steinbach wrote:
 
> This reminds me strongly of the tortoise's denial arguments in
> Hofstadter's "Gödel, Escher, Bach: An Eternal Golden Braid".
 
> I recommend that book.
nice try.
"Öö Tiib" <ootiib@hot.ee>: Dec 26 03:01AM -0800

On Thursday, 26 December 2019 02:55:04 UTC+2, Pavel wrote:
> >> (3.2) — Each identifier that begins with an underscore is reserved to
> >> the implementation for use as a name in
> >> the global namespace.
 
Sometimes I notice hieroglyph fi used instead of fi in normative texts.
Like "identifier". Perhaps there is saboteur among the language lawyers
that wants to make it harder to search the texts.
 
> >> used by otherwise than by C++ implementation
 
> > The parenthetical remark does not follow from anything.
> except it follows from 3.2 cited right above
 
I understand how the sentence may be interpreted like that out of
context but that interpretation does not make sense in C++.
 
Names have scope in C++ (or can lack it on case of macros and keywords).
So "as names in the global namespace" means that it is where the
rule applies. Similarly "for any use" means that such names are
reserved for any (scoped or scope-less) usage.
 
Characters of Alice in Wonderland kept constantly misinterpreting
meanings of sentences like that so perhaps it is just limitation
of human languages. Or can you propose better wording?
 
 
> >> namespace.
 
> > ... or namespace `std`.
> *that* is what does not seem to follow from anything.
 
There standard has chosen to other way of reserving, the menace
of undefined behavior when user touches namespace std in wrong
way:
"The behavior of a C++ program is undefined if it adds declarations
or definitions to namespace std or to a namespace within namespace
std unless otherwise specified. A program may add a template
specialization for any standard library template to namespace std
only if the declaration depends on a user-defined type and the
specialization meets the standard library requirements for the original
template and is not explicitly prohibited."
 
 
> > Rather, the question is where you get these ideas.
> Oh, the answer to this one is simple: boolean logic applied to A and B
> above.
 
English does not unfortunately translate into boolean logic.
No human language does.
 
"Öö Tiib" <ootiib@hot.ee>: Dec 26 03:20AM -0800

On Thursday, 26 December 2019 13:01:25 UTC+2, Öö Tiib wrote:
> only if the declaration depends on a user-defined type and the
> specialization meets the standard library requirements for the original
> template and is not explicitly prohibited."
 
Note that by your interpretation, Pavel, standard is violating itself:
<https://en.cppreference.com/w/cpp/utility/functional/placeholders>
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: