But if we can do more to support C programmers moving over to C++ it would be a win for both camps.
"The fact that you can't resize a string or vector without initializing its elements is a measurable and significant performance problem for some applications; I have seen people invent their own string type or do truly horrible things to std::string (directly poking at its internals) to circumvent that."
I have seen a lot of code like this that I'd like to not write/fix/use:
s += "hello";
char* ptr = malloc(s.length()+1);
if (!ptr)
return nullptr;
strcpy(ptr, s.data());
return ptr;
}
There are various reasons people use string like this (but vector also). These are:
1. They just intend to return a string eventually but need data from a C like API. Fill can be expensive.
2. They need some RAII thing so if there's an exception the destructor will release the memory.
3. They could use unique_ptr but they want to do some string'y things first.
4. They want string for the small buffer optimization.
5. They sometimes need to return the buffer to C.
char* do_something_for_c_library()
{
std::string s;
auto len = SomeCAPI(s.uinitialized_data_at(0, n+1), n);
s.resize(len);
s+="hello";
return s.detach_and_string_terminate(); // And provide basic detach also.
}
s.uinitialized_data_at does this:
Ensures that a range of elements starting at 0 for length n exists.
and if it doesn't it extends it without initialization.
The starting position should exist or it's an error unless it is 0 and the string is empty.
if it can't allocate or the offset or length is bad the it throws a std::logic_error(); explaining the problem.
I don't see why we can't provide this same API for vector.
detach_and_string_terminate() could just be enable_if'd only types of char/wchar_t/unsigned char/char32_t/char16_t.
unintialized_data_at() could just be enabled for these types too for now if that helps safety.
T *t = new T[256];
vector<T> tv(256, ...);
Do we really need to wait 3 years for ALL of this?
But is providing the minimum to support a minimum of the uninitialized_data_at routine so hard that we need to wait?
If there's something better. What is it?
Several reasons.
First, `basic_string` is intended to be able to have small string optimization (SSO). This means that strings below a certain size are stored internally rather than allocating memory. Thus, your "detach" function doesn't "detach" something in all cases.
Second, `basic_string` and `vector` both allocate memory based on provided allocators. So... how will the user destroy it? They cannot call `delete[]` on it, since it was not allocated with `new[]`. The only way to destroy this object us to use the same allocator that was used to allocate it, or a compatible one. Not only that, the person receiving the pointer has no idea how many objects are in the array, so unless `T` has a trivial destructor, you need to know how many items to destroy. And you need to remember to destroy them in reverse order.
Third, your APIs are really bad. Inserting default-initialized objects shouldn't use radically different APIs from inserting value-initialized objects. Your API also assumes that `T` is a type which can tolerate being uninitialized. We shouldn't make APIs that break the C++ object model; we should make them that actually work with that model.
The goal is this:
T *t = new T[256];
vector<T> tv(256, ...);
Both of these arrays should perform the same amount of initializing of their respective arrays. If `T` is trivially default constructible, then both of these will be uninitialized. If `T` has a non-trivial default constructor, then it will be called 256 times in both cases. Because by the rules of C++, that's what `T` requires in order to be a live object.
The goal should not be to have `vector/string` emulate `malloc`/casting/etc. If you want to violate the C++ object model, that's your business, but we shouldn't have standard library types let you do that.Do we really need to wait 3 years for ALL of this?
Yes. Be glad it's just 3 years.
But is providing the minimum to support a minimum of the uninitialized_data_at routine so hard that we need to wait?
You cannot get something into the standard right now just because you really want it. C++17 was feature-complete months ago. The ship has sailed; it's not coming back into port.
The next ship launches in 3 years. Get ready for it.
If there's something better. What is it?
Well, there's what I already suggested.
I also spent a little time thinking about a memory detachment API for vector, one that would actually recognize things like the fact that allocators exist ;) Since then, we've had the introduction of `map`/`set` extract/merge functions, and we see an alternate way to handle transfer of such objects.
The design of such an API should mirror them, not deal in direct pointers to something. Also, such a design should include the ability to hand the system existing memory (and an allocator for deleting it), which can then be transferred into a `vector`/`string`.
The goal should not be to have `vector/string` emulate `malloc`/casting/etc. If you want to violate the C++ object model, that's your business, but we shouldn't have standard library types let you do that.Do we really need to wait 3 years for ALL of this?
Yes. Be glad it's just 3 years.
But is providing the minimum to support a minimum of the uninitialized_data_at routine so hard that we need to wait?
You cannot get something into the standard right now just because you really want it. C++17 was feature-complete months ago. The ship has sailed; it's not coming back into port.
The next ship launches in 3 years. Get ready for it.If there's something better. What is it?
Well, there's what I already suggested.
I also spent a little time thinking about a memory detachment API for vector, one that would actually recognize things like the fact that allocators exist ;) Since then, we've had the introduction of `map`/`set` extract/merge functions, and we see an alternate way to handle transfer of such objects.
The design of such an API should mirror them, not deal in direct pointers to something. Also, such a design should include the ability to hand the system existing memory (and an allocator for deleting it), which can then be transferred into a `vector`/`string`.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/07f6e085-f75b-41f0-b42d-8a2704dbdb9a%40isocpp.org.
On 9 January 2017 at 17:35, Nicol Bolas <jmck...@gmail.com> wrote:Several reasons.
First, `basic_string` is intended to be able to have small string optimization (SSO). This means that strings below a certain size are stored internally rather than allocating memory. Thus, your "detach" function doesn't "detach" something in all cases.
Second, `basic_string` and `vector` both allocate memory based on provided allocators. So... how will the user destroy it? They cannot call `delete[]` on it, since it was not allocated with `new[]`. The only way to destroy this object us to use the same allocator that was used to allocate it, or a compatible one. Not only that, the person receiving the pointer has no idea how many objects are in the array, so unless `T` has a trivial destructor, you need to know how many items to destroy. And you need to remember to destroy them in reverse order.
Third, your APIs are really bad. Inserting default-initialized objects shouldn't use radically different APIs from inserting value-initialized objects. Your API also assumes that `T` is a type which can tolerate being uninitialized. We shouldn't make APIs that break the C++ object model; we should make them that actually work with that model.
The goal is this:
T *t = new T[256];
vector<T> tv(256, ...);
Both of these arrays should perform the same amount of initializing of their respective arrays. If `T` is trivially default constructible, then both of these will be uninitialized. If `T` has a non-trivial default constructor, then it will be called 256 times in both cases. Because by the rules of C++, that's what `T` requires in order to be a live object.If you only provide that, you have not solved the complete problem. Sometimes the requirements do include the ability to directly construct a sequence of T objects in place within a vector, in ways that emplace does not support.
One (slightly scary) approach would be:1) permit the user to construct objects in trailing storage of a vector/string, so long as capacity is large enough, and2) provide a resize_already_initialized(size_t) member to resize the container so that those elements are part of its size, without constructing new Ts over the top of them
Obviously if (1) somehow fails or throws, destroying the elements it created is its problem, and triggering reallocation during (1) would be bad.
Several reasons.
First, `basic_string` is intended to be able to have small string optimization (SSO). This means that strings below a certain size are stored internally rather than allocating memory. Thus, your "detach" function doesn't "detach" something in all cases.That's not a reason for doing nothing. That's just a description of how things are that doesn't forward anything. I don't know why so many replies are structured like this.Detach could allocate and copy if it must. If that fails it returns nullptr. Or uninitialized_data_at can do the allocate copy if directed, that can fail anyway so that seems the fine place to do that. We can indicate that in a parameter etc.There are ways forward here.
Second, `basic_string` and `vector` both allocate memory based on provided allocators. So... how will the user destroy it? They cannot call `delete[]` on it, since it was not allocated with `new[]`. The only way to destroy this object us to use the same allocator that was used to allocate it, or a compatible one. Not only that, the person receiving the pointer has no idea how many objects are in the array, so unless `T` has a trivial destructor, you need to know how many items to destroy. And you need to remember to destroy them in reverse order.
Third, your APIs are really bad. Inserting default-initialized objects shouldn't use radically different APIs from inserting value-initialized objects. Your API also assumes that `T` is a type which can tolerate being uninitialized. We shouldn't make APIs that break the C++ object model; we should make them that actually work with that model.I said we could enable_if that and that these could be free. You seem to be ignoring that fact or didn't see it. I don't see a problem with the idea.And C++ already has plenty of 'get outs' for doing what needs to be done if it needs to be done. We should make API's that enable us to do what we need to do. You don't have to call them if you don't need what it offers. So I don't buy your argument.
vector<T> v;
SomeCAPI(v.uinitialized_data_at(0, n), n);
vector<T> v(n, std::default_init);
SomeCAPI(v.data(), v.size());
The goal is this:
T *t = new T[256];
vector<T> tv(256, ...);
Both of these arrays should perform the same amount of initializing of their respective arrays. If `T` is trivially default constructible, then both of these will be uninitialized. If `T` has a non-trivial default constructor, then it will be called 256 times in both cases. Because by the rules of C++, that's what `T` requires in order to be a live object.That's great but why does my suggestion break that or hinder that.
So why do we have to wait for that?Is there any guarantee we will even get that?
If there's something better. What is it?
Well, there's what I already suggested.
I also spent a little time thinking about a memory detachment API for vector, one that would actually recognize things like the fact that allocators exist ;) Since then, we've had the introduction of `map`/`set` extract/merge functions, and we see an alternate way to handle transfer of such objects.
The design of such an API should mirror them, not deal in direct pointers to something. Also, such a design should include the ability to hand the system existing memory (and an allocator for deleting it), which can then be transferred into a `vector`/`string`.I don't see how you can avoid dealing with a pointer when you (I) want to be able to return a pointer to C here.
On Monday, January 9, 2017 at 8:57:39 PM UTC-5, gmis...@gmail.com wrote:
Several reasons.
First, `basic_string` is intended to be able to have small string optimization (SSO). This means that strings below a certain size are stored internally rather than allocating memory. Thus, your "detach" function doesn't "detach" something in all cases.That's not a reason for doing nothing. That's just a description of how things are that doesn't forward anything. I don't know why so many replies are structured like this.Detach could allocate and copy if it must. If that fails it returns nullptr. Or uninitialized_data_at can do the allocate copy if directed, that can fail anyway so that seems the fine place to do that. We can indicate that in a parameter etc.There are ways forward here.
Second, `basic_string` and `vector` both allocate memory based on provided allocators. So... how will the user destroy it? They cannot call `delete[]` on it, since it was not allocated with `new[]`. The only way to destroy this object us to use the same allocator that was used to allocate it, or a compatible one. Not only that, the person receiving the pointer has no idea how many objects are in the array, so unless `T` has a trivial destructor, you need to know how many items to destroy. And you need to remember to destroy them in reverse order.
Third, your APIs are really bad. Inserting default-initialized objects shouldn't use radically different APIs from inserting value-initialized objects. Your API also assumes that `T` is a type which can tolerate being uninitialized. We shouldn't make APIs that break the C++ object model; we should make them that actually work with that model.I said we could enable_if that and that these could be free. You seem to be ignoring that fact or didn't see it. I don't see a problem with the idea.And C++ already has plenty of 'get outs' for doing what needs to be done if it needs to be done. We should make API's that enable us to do what we need to do. You don't have to call them if you don't need what it offers. So I don't buy your argument.
C++ has ways to do things that are illegal in some circumstances because those tools also permit you to do legal things that you would not otherwise be able to do. I believe that the circumstances where what you're wanting to do is actually legal C++ code can be done in ways that don't require tools that allow you to also do illegal things.
For example, a C API cannot create a non-trivial C++ object (if you want to get really technical, a C API cannot begin the lifetime of a C++ object at all, but lets pretend that trivial types can be excepted). As such, you cannot legally hand the memory of a `vector<T>` to a C API to be initialized unless `T` is trivial. Therefore, the ability to default initialize a `vector<T>` is all you need to avoid the performance penalty, since default initialization is a no-op.
Your API would look like this:
vector<T> v;
SomeCAPI(v.uinitialized_data_at(0, n), n);
My API would look like this:
vector<T> v(n, std::default_init);
SomeCAPI(v.data(), v.size());
But they would have the same performance: a single allocation of a block of `n` objects, with no initialization of that array.
So why use an API that is oddball and non-standard looking instead of an API that looks like normal `vector` mechanisms? Your way makes using "uninitialized" data look special-case, like you're cheating or something. My way makes it look normal, just like you had done `new T[n]` or whatever.
Because it is normal. You're not cheating; every step is 100% legal C++. You're not pretending that C APIs can begin the lifetime of C++ objects. You're creating an array of live C++ objects and passing them along to someone else who will trivially copy into them.
So why do we need an API that looks so alien to how the API currently works?
The goal is this:
T *t = new T[256];
vector<T> tv(256, ...);
Both of these arrays should perform the same amount of initializing of their respective arrays. If `T` is trivially default constructible, then both of these will be uninitialized. If `T` has a non-trivial default constructor, then it will be called 256 times in both cases. Because by the rules of C++, that's what `T` requires in order to be a live object.That's great but why does my suggestion break that or hinder that.
Because it doesn't look like regular `vector` stuff.
So why do we have to wait for that?Is there any guarantee we will even get that?
There's no guarantee you'll get yours either.
If there's something better. What is it?
Well, there's what I already suggested.
I also spent a little time thinking about a memory detachment API for vector, one that would actually recognize things like the fact that allocators exist ;) Since then, we've had the introduction of `map`/`set` extract/merge functions, and we see an alternate way to handle transfer of such objects.
The design of such an API should mirror them, not deal in direct pointers to something. Also, such a design should include the ability to hand the system existing memory (and an allocator for deleting it), which can then be transferred into a `vector`/`string`.I don't see how you can avoid dealing with a pointer when you (I) want to be able to return a pointer to C here.
You can want whatever you like, but that doesn't change the fact that it's simply not possible. Why? Because you're leaking memory. Or worse, breaking the heap.
`free` cannot be called on memory allocated by `new` or `allocator::allocate` or whatever other allocator you may have used (unless that allocator explicitly uses `malloc`, of course). Therefore, the memory generated by C++ containers cannot be destroyed by C. So either C is going to try to `free` this memory and corrupt the heap, or the C API is going to call back into your code in order to free it.
It should also be noted that, at least in my experience, there aren't a lot of C APIs like this, which genuinely adopt memory allocated by external code. Lua, Cairo, etc, I can't think of one that adopts memory by return values of a callback. Generally speaking, they copy it from you.
Can you give an example where a return value from a callback is intended by a C API to be memory which is dynamically allocated in such a way that the C system can deallocate it?
Generally speaking, when transitioning from one system to another, you will need to marshal your data: to copy it from your internal data structures/memory pools into those compatible with the other system. This is inevitable and natural. And most of the C APIs I know of tend to hold to that. They'll fill in arrays of memory with data. But they almost never cross allocations like this, and for more reasons than just playing ball with C++ APIs. C programmers sometimes need to write their own heap code, and that means other systems can't deallocate memory they allocate. So in my experience, C APIs don't frequently adopt memory.
So I question the motivation for this part of your idea.
But for C++17, if it was just want unintialized_resize() or data_at or whatever I'd be happy. We must have this for C++20 I think, I'd ideally like this function sooner even if non standard to test with.
On Monday, January 9, 2017 at 9:03:03 PM UTC-5, Richard Smith wrote:On 9 January 2017 at 17:35, Nicol Bolas <jmck...@gmail.com> wrote:Several reasons.
First, `basic_string` is intended to be able to have small string optimization (SSO). This means that strings below a certain size are stored internally rather than allocating memory. Thus, your "detach" function doesn't "detach" something in all cases.
Second, `basic_string` and `vector` both allocate memory based on provided allocators. So... how will the user destroy it? They cannot call `delete[]` on it, since it was not allocated with `new[]`. The only way to destroy this object us to use the same allocator that was used to allocate it, or a compatible one. Not only that, the person receiving the pointer has no idea how many objects are in the array, so unless `T` has a trivial destructor, you need to know how many items to destroy. And you need to remember to destroy them in reverse order.
Third, your APIs are really bad. Inserting default-initialized objects shouldn't use radically different APIs from inserting value-initialized objects. Your API also assumes that `T` is a type which can tolerate being uninitialized. We shouldn't make APIs that break the C++ object model; we should make them that actually work with that model.
The goal is this:
T *t = new T[256];
vector<T> tv(256, ...);
Both of these arrays should perform the same amount of initializing of their respective arrays. If `T` is trivially default constructible, then both of these will be uninitialized. If `T` has a non-trivial default constructor, then it will be called 256 times in both cases. Because by the rules of C++, that's what `T` requires in order to be a live object.If you only provide that, you have not solved the complete problem. Sometimes the requirements do include the ability to directly construct a sequence of T objects in place within a vector, in ways that emplace does not support.
That is a problem best solved by allowing `emplace` to construct an object in ways that it does not currently support.
What in particular was a circumstance you were thinking of?
One (slightly scary) approach would be:1) permit the user to construct objects in trailing storage of a vector/string, so long as capacity is large enough, and2) provide a resize_already_initialized(size_t) member to resize the container so that those elements are part of its size, without constructing new Ts over the top of themObviously if (1) somehow fails or throws, destroying the elements it created is its problem, and triggering reallocation during (1) would be bad.
I'm not sure why we should encourage (1) happening outside of the presence of (2). Or rather, I don't know why it is necessary to do it that way.
Can you give an example? One that is actually legal C++ under the current object model?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3ef49ad2-3e73-4d58-872d-fab5f138e22b%40isocpp.org.
On Tuesday, January 10, 2017 at 5:19:44 PM UTC+13, Nicol Bolas wrote:On Monday, January 9, 2017 at 8:57:39 PM UTC-5, gmis...@gmail.com wrote:
Several reasons.
First, `basic_string` is intended to be able to have small string optimization (SSO). This means that strings below a certain size are stored internally rather than allocating memory. Thus, your "detach" function doesn't "detach" something in all cases.That's not a reason for doing nothing. That's just a description of how things are that doesn't forward anything. I don't know why so many replies are structured like this.Detach could allocate and copy if it must. If that fails it returns nullptr. Or uninitialized_data_at can do the allocate copy if directed, that can fail anyway so that seems the fine place to do that. We can indicate that in a parameter etc.There are ways forward here.
Second, `basic_string` and `vector` both allocate memory based on provided allocators. So... how will the user destroy it? They cannot call `delete[]` on it, since it was not allocated with `new[]`. The only way to destroy this object us to use the same allocator that was used to allocate it, or a compatible one. Not only that, the person receiving the pointer has no idea how many objects are in the array, so unless `T` has a trivial destructor, you need to know how many items to destroy. And you need to remember to destroy them in reverse order.
Third, your APIs are really bad. Inserting default-initialized objects shouldn't use radically different APIs from inserting value-initialized objects. Your API also assumes that `T` is a type which can tolerate being uninitialized. We shouldn't make APIs that break the C++ object model; we should make them that actually work with that model.I said we could enable_if that and that these could be free. You seem to be ignoring that fact or didn't see it. I don't see a problem with the idea.And C++ already has plenty of 'get outs' for doing what needs to be done if it needs to be done. We should make API's that enable us to do what we need to do. You don't have to call them if you don't need what it offers. So I don't buy your argument.
C++ has ways to do things that are illegal in some circumstances because those tools also permit you to do legal things that you would not otherwise be able to do. I believe that the circumstances where what you're wanting to do is actually legal C++ code can be done in ways that don't require tools that allow you to also do illegal things.Legal and illegal are just points in time. What is today illegal can often be made legal depending on the will and reasoning.But something being illegal today in of itself isn't interesting.
For example, a C API cannot create a non-trivial C++ object (if you want to get really technical, a C API cannot begin the lifetime of a C++ object at all, but lets pretend that trivial types can be excepted). As such, you cannot legally hand the memory of a `vector<T>` to a C API to be initialized unless `T` is trivial. Therefore, the ability to default initialize a `vector<T>` is all you need to avoid the performance penalty, since default initialization is a no-op.
Your API would look like this:
vector<T> v;
SomeCAPI(v.uinitialized_data_at(0, n), n);yes, I'm not attached to the API, but nor do I have a problem with it. I just want the ability.
My API would look like this:
vector<T> v(n, std::default_init);
SomeCAPI(v.data(), v.size());
But they would have the same performance: a single allocation of a block of `n` objects, with no initialization of that array.I'm fine with your API but it's less flexible than my API unless I miss understand what yours implies.And I feel I'm not appreciating what yours implies Can you extend v without getting more unwanted initialization with your API? i.e. Is v.resize(10000) going to do the right thing her and not zero fill where n in the initial call is say 1 or 0.
So why use an API that is oddball and non-standard looking instead of an API that looks like normal `vector` mechanisms? Your way makes using "uninitialized" data look special-case, like you're cheating or something. My way makes it look normal, just like you had done `new T[n]` or whatever.I don't find my API that oddball but I'm not hung up on my api, I just want the feature of unintialized allocation.Because it is normal. You're not cheating; every step is 100% legal C++. You're not pretending that C APIs can begin the lifetime of C++ objects. You're creating an array of live C++ objects and passing them along to someone else who will trivially copy into them.I'm not pretending that as far as I know. My API isn't asking C to begin life here. But I'm sure we'll work out whatever misunderstanding I or you have here later.So why do we need an API that looks so alien to how the API currently works?I don't need anything alien. I just want something that gives me unintialized allocation.
When I mooted what I need, you started talking about language changes as a requirement to progress.
It's you that's on your high horse because it's you that is making the 'smart' comments!You have no idea what I do or don't contribute towards C++ or how I contribute so I don't see where you get off being so derisory?And given I do contribute, I'm entitled to express what I think is important or a must for C++ as anybody else without having to intimately make any such proposal happen that I wish to comment on. It's ridiculous to think otherwise.
For example, everybody on the planet thinks C++ must have modules but I can assure you everyone on the planet isn't beavering away working on it! But they'll sure tell you we must have it! So why should I be singled out any different? Are you going to now get on reddit and be derisory to all those folks too?
On Tuesday, January 10, 2017 at 8:24:01 AM UTC-5, gmis...@gmail.com wrote:It's you that's on your high horse because it's you that is making the 'smart' comments!You have no idea what I do or don't contribute towards C++ or how I contribute so I don't see where you get off being so derisory?And given I do contribute, I'm entitled to express what I think is important or a must for C++ as anybody else without having to intimately make any such proposal happen that I wish to comment on. It's ridiculous to think otherwise.
You have the right to express that you feel something is important. That's fine, and I think D. B. was kinda out of line in trying to upbraid you for it.
However, you do need to make a distinction between "I believe X is critical" and "X is critical". You can argue that something is crucial to C++. But it'd be a lot easier of an argument to make if you have other people around who agree with you.
When I argue that unified call syntax, or something like it, is a vital feature for future C++, I can at least point to the disappointment other people have in the lack of this feature in C++17 as evidence for it. Thus far, the only evidence you have that this is a critical C++ feature is... your word.
Now, I do think being able to default-initialize things really is important. But that doesn't mean we should accept a half-solution (let alone one that's as laced with C-idioms as yours) when we can get a whole one.For example, everybody on the planet thinks C++ must have modules but I can assure you everyone on the planet isn't beavering away working on it! But they'll sure tell you we must have it! So why should I be singled out any different? Are you going to now get on reddit and be derisory to all those folks too?
There are many differences between modules and your proposal:
1: Modules are a compiler feature. A very, very complex one. Implementing it requires deep knowledge of a complier. Your idea is a pure-library change. Implementing it requires being a C++ programmer.
2: Modules are actively being implemented by 2 major compiler vendors. Your idea is actively being implemented by... nobody.
So suggesting that you provide a proof-of-concept implementation is not unreasonable.
Also... *nothing* is stopping you from moving ahead with your proposal
anyway. Maybe the committee will think it's a fabulous idea and move
forward with it anyway. Maybe they'll have the same reaction:
unconvinced without further evidence. Very little¹ that happens on this
forum reflects how you *must* proceed. Rather, it serves as an
approximation of how the committee is *likely* to respond to a proposal.
Ignore or abide by that at your own risk.
(¹ Comments made by committee members are of course not to be set aside
lightly, as they will almost certainly happen in actual committee also.)
> The recent enum cast proposal is a good example [...] why am I
> getting flack and not them?
I would disagree with the claim that Maciej is not getting flack :-).
> People should just assist with what's presented and help complete the
> incomplete if they want to, or stay clear.
Here, I am not sure I agree. There is a cost to dealing with bad
proposals, especially by the time they get to an actual committee
meeting. Allowing a bad proposal to get that far can end up wasting a
lot more time than if it was killed off early.
I also am not convinced that allowing a terrible proposal to make it all
the way to committee isn't doing the *proposer* a disservice, as well.
If I have an idea that is really terrible, I want to know that people
feel that way. At least so I'm prepared for it at committee, but also so
that maybe I'm not wasting time on a proposal that has no chance of success.
--
Matthew
--
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/ofyByk1VorU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/587663E0.9050800%40gmail.com.
On 2017-01-11 04:51, gmis...@gmail.com wrote:
> I shouldn't need to go hacking a C and C++ memory allocator to prove
> it's possible for the former to be able to able to de-allocate for
> the latter
Um... good luck with that.
Also... *nothing* is stopping you from moving ahead with your proposal
anyway. Maybe the committee will think it's a fabulous idea and move
forward with it anyway. Maybe they'll have the same reaction:
unconvinced without further evidence. Very little¹ that happens on this
forum reflects how you *must* proceed. Rather, it serves as an
approximation of how the committee is *likely* to respond to a proposal.
Ignore or abide by that at your own risk.No, nothing is stopping anybody, but we should we encourage discouragement?
I should add that so far the enum cast proposal is a model of what I do want to see.1. Somebody has the essence of a good idea.2. Possibly not be best API exactly as proposed, but it's of no concern. The idea is good.3. So everyone rallies around and morphs it into something to with a better API.4. OP writes it all up and submits a proposal.