Friday, July 7, 2017

Digest for comp.lang.c++@googlegroups.com - 25 updates in 4 topics

"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 01:08PM +0200

It so happens that I don't have any Apple equipment, and since I'm
rather poor I can't afford to just buy it.
 
I've just implemented the following declaration for Windows and Linux:
 
<url:
https://github.com/alf-p-steinbach/stdlib/blob/master/source/extension/process_command_line.declarations.hpp>
 
 
inline auto command_line() -> string;
 
class Command_line_args
{
private:
vector<string> items_;
 
public:
auto begin() const { return items_.begin(); }
auto end() const { return items_.end(); }
 
auto size() const -> Size { return items_.size(); }
 
auto operator[]( Index const i ) const
-> ref_<const string>
{ return items_.at( i ); }
 
inline Command_line_args();
};
 
 
Here's the Linux implementation (it appears to work, in Ubuntu in a
Virtual Box):
 
<url:
https://github.com/alf-p-steinbach/stdlib/blob/master/source/_impl/linux_process_command_line.hpp>
 
 
namespace impl {
inline auto get_command_line_data()
-> string
{
const string path = "/proc/" + to_string( getpid() ) +
"/cmdline";
ifstream f{ path };
hopefully( not f.fail() )
or fail( "stdlib::impl::get_command_line_data - failed
to open "" + path + """ );
string result;
getline( f, result )
or fail( "stdlib::impl::get_command_line_data - failed
to read "" + path + """ );
return result;
}
} // namespace impl
 
inline auto process::command_line()
-> string
{
// TODO: needs quoting of parts as necessary.
string result = impl::get_command_line_data();
replace( result.begin(), result.end(), '\0', ' ' );
return result;
};
 
inline process::Command_line_args::Command_line_args()
{
const string s = impl::get_command_line_data();
int i = 0;
for( char const* p = &s[0]; *p; p += strlen( p ) + 1 )
{
items_.push_back( p );
}
}
 
 
In addition to never having done anything on the Mac except helping a
person type a character that wasn't directly available on the keyboard,
I've never cooperated with anyone on GitHub. I guess it's just a matter
of the other person have a username there so can be added as maintainer
on the project? If you can help to write corresponding code for some
other system than Windows and Linux that would be great!
 
And I'm not really very familiar with Linux either, so, for example, I
have no ready knowledge about how to quote the command line – the TODO:
comment in the code above – so that it can be parsed back into its
constituent argument parts? Or is that not possible perhaps?
 
 
Cheers!,
 
- Alf
Ralf Goertz <me@myprovider.invalid>: Jul 07 02:25PM +0200

Am Fri, 7 Jul 2017 13:08:52 +0200
> have no ready knowledge about how to quote the command line – the
> TODO: comment in the code above – so that it can be parsed back into
> its constituent argument parts? Or is that not possible perhaps?
 
There is no need for this line:
 
replace( result.begin(), result.end(), '\0', ' ' );
 
under Linux, since the cmdline file in proc already separates the
arguments by '\0'. Furthermore, you can change this line:
 
const string path = "/proc/" + to_string( getpid() ) + "/cmdline";
 
to this:
 
const string path = "/proc/self/cmdline";
 
since in proc you get a link to your own pid named "self".
 
HTH Ralf
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 07 02:26PM +0100

On 07/07/2017 12:08, Alf P. Steinbach wrote:
> { return items_.at( i ); }
 
> inline Command_line_args();
> };
 
1) Member data should come after member functions.
2) Private should come after public.
3) Your use of auto in a class interface is inappropriate; auto use at
client site is fine but at API level it just obfuscates: what is the
fucking return type?
4) Your mixture of capital letter and underscores for class names is
egregious.
5) std::vector::at() can throw whilst std::vector::operator[] doesn't so
it is confusing to mix the two as you are doing.
6) Your use of inline keyword for in-class function declaration seems bogus.
 
/Flibble
Gareth Owen <gwowen@gmail.com>: Jul 07 04:31PM +0100


> 1) Member data should come after member functions.
 
Beside "convention", is there any reason for this rule?
 
My tendency is to group public data and public functions together, so
the user can see the whole API/contract/"interface" in one place.
 
> 2) Private should come after public.
 
This one makes sense.
 
<Eminently sensible stuff snipped>
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 05:46PM +0200

On 07-Jul-17 2:25 PM, Ralf Goertz wrote:
 
> replace( result.begin(), result.end(), '\0', ' ' );
 
> under Linux, since the cmdline file in proc already separates the
> arguments by '\0'.
 
<url: http://en.cppreference.com/w/cpp/algorithm/replace>
 
It replaces every `'\0'` with a space, to synthesize a possible original
command line like the one in Windows. The idea is to provide
conceptually the same on all platforms. Hence the need for quoting for
the general case, if I understand this correctly (I'm not 100% sure).
 
 
 
> to this:
 
> const string path = "/proc/self/cmdline";
 
> since in proc you get a link to your own pid named "self".
 
Thanks! :)
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 06:13PM +0200

On 07-Jul-17 3:26 PM, Mr Flibble wrote:
>> };
 
> 1) Member data should come after member functions.
> 2) Private should come after public.
 
I have a different and, I believe, just as well-informed opinion.
 
 
> 3) Your use of auto in a class interface is inappropriate; auto use at
> client site is fine but at API level it just obfuscates: what is the
> fucking return type?
 
You could write out the return type as `vector<string>::const_iterator`,
but that's just brittle and without value. I think the case above must
surely have been one of the motivating cases for C++14 deduced return
type. We don't care about the actual concrete iterator type: it can be
whatever it is, and best if it automatically follows the container type
and possible changes of constness of the member function and so on.
 
 
> 4) Your mixture of capital letter and underscores for class names is
> egregious.
 
I capitalize type names.
 
E.g. in some cases it's convenient to have a variable and a type of the
same name, just with different capitalization, and also, in some cases
it's convenient to have a type with the same name as a core language or
standard library type, except for capitalization. So I've found it to be
a nice convention. I've used many different conventions over the years.
 
 
> 5) std::vector::at() can throw whilst std::vector::operator[] doesn't so
> it is confusing to mix the two as you are doing.
 
As I see it, the need for superfast indexing of command line arguments
is non-existent.
 
Then convenient range-checking can be provided at no cost, so it is. :)
 
Since it's part of the interface (contract) of this class, it's in the
interface, and it's hereby proved that that contract is noticed, thanks.
 
 
> 6) Your use of inline keyword for in-class function declaration seems
> bogus.
 
It tells you (very clearly) that the definition of that function is
and/or should be provided textually inline in header code.
 
And it tells you that, not as a hint that you'd have to figure out, but
as absolutely required by the language rules,
 
except, to be pedantic, that the standard allows code to be provided by
a database or magic or whatever, not necessarily as files.
 
The `inline` keyword has to be either on the in-class declaration, or on
the definition, or both.
 
Choosing to place it only on the definition would communicate the least,
the minimum, to a reader of the code, opposite of what I want.
 
 
Cheers!,
 
- Alf
Manfred <noname@invalid.add>: Jul 07 08:38PM +0200

On 7/7/2017 5:46 PM, Alf P. Steinbach wrote:
> command line like the one in Windows. The idea is to provide
> conceptually the same on all platforms. Hence the need for quoting for
> the general case, if I understand this correctly (I'm not 100% sure).
 
I, for one, find the *nix cmdline arg handling definitely better
designed than Windows's (which in fact does nothing useful with it), so
why the attempt to build a Windows-like command line, and not the other
way around?
If you wish, your library could set up a decent argc/argv set from the
Windows command line, e.g. including wildchar expansion and the like.
A lot could be done in that direction (ref the sh/bash manpage) although
I cannot say if it can be worth the effort at all on Windows, given the
limited use of cmdline args on this platform.
On the other hand, a program targeted for *nix most probably wants to
use the native argc/argv, since they are quite effectively preprocessed
by the shell, and it wants to make use of its features.
 
I am not sure what you mean about need for quoting, anyway on *nix
quoting is processed by the shell, and it is removed after interpreting
that a quoted string has to be parsed in its well defined way (e.g. as a
single argument if it includes spaces - the QUOTING subsection of the
bash manpage is two pages of dense specification) before passing the
result to the program.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 09:33PM +0200

On 07-Jul-17 8:38 PM, Manfred wrote:
> designed than Windows's (which in fact does nothing useful with it), so
> why the attempt to build a Windows-like command line, and not the other
> way around?
 
I provide both. See the interface presented in original posting. I like
the Winnie the Pooh response to "honey or syrup?", namely "both, thank
you". :)
 
 
> If you wish, your library could set up a decent argc/argv set from the
> Windows command line,
 
It does.
 
 
> e.g. including wildchar expansion and the like.
 
Yes, I've considered that, thanks!, but, first of all, I must do one
thing at a time. And secondly, as opposed to providing command line
arguments in UTF-8, which is both an implementation fix and a core
language + standard library design level fix, I think wildchar expansion
would be a distinct /extension/ of the C++ standard library. In
contrast, the intent of /stdlib/ is just to fix the implementation, to
provide a more practically usable implementation. Wrt. that goal of
limitation providing command line arguments is border-line already, and
necessarily treated as an extension, but I think it may be crucial to
enable and foster adoption of the library. For only if /stdlib/ makes
client code at least as convenient or more convenient than with the
/NoWide/ library (adopted in Boost last month), will it fly, I think.
 
But doing that by default, as MinGW g++ unfortunately does for the
arguments of `main`, breaks expectation in Windows: it does not conform
to the convention established by the main compiler for the platform.
 
For example, the Windows / Visual C++ approach allows you to write a
`fastmove` program that accepts `fastmove *.bah someplace\*.foo`. That
will just not work with with MinGW g++'s default. And I don't know any
way to tell MinGW g++ to not do that. :(
 
The current design of fetching the data from the OS on all systems, is
in part motivated by the need to fix MinGW g++'s effectively broken
implementation: since I fail to fix it, I provide an alternative.
 
And partly this design is motivated by MinGW g++ not conforming to the
Visual C++ convention wrt. to the `__argv` and `__argc` variables (it's
a Windows thing). Changing these works with Visual C++, but doesn't
affect the arguments that MinGW g++ passes to `main`. Thus it's
apparently not possible with a transparent fix of MinGW g++'s behavior,
and the /NoWide/ solution of passing on argc and argv, is abhorrent to
me (I also suspect that it's simply wrong when pitted against MinGW g++
and wildcard arguments, but I haven't tested that yet).
 
 
> A lot could be done in that direction (ref the sh/bash manpage) although
> I cannot say if it can be worth the effort at all on Windows, given the
> limited use of cmdline args on this platform.
 
Command line args are used most every time you "open" a file in Windows,
e.g. by double-clicking it.
 
 
> On the other hand, a program targeted for *nix most probably wants to
> use the native argc/argv, since they are quite effectively preprocessed
> by the shell, and it wants to make use of its features.
 
Yes.
 
Except where one makes use of some 3rd party top level code, where one
doesn't have access to the `main` arguments.
 
 
> single argument if it includes spaces - the QUOTING subsection of the
> bash manpage is two pages of dense specification) before passing the
> result to the program.
 
Well I meant the `command_line()` function to produce a possible command
line that, when used to create a new process, would reproduce exactly
the command line args here.
 
Client code that needs the individual arguments can just access them via
`Command_line_args`.
 
 
Cheers!, & thanks for your feedback,
 
- Alf
Daniel <danielaparker@gmail.com>: Jul 07 12:38PM -0700

On Friday, July 7, 2017 at 9:26:38 AM UTC-4, Mr Flibble wrote:
 
> > inline Command_line_args();
> > };
 
> 1) Member data should come after member functions.
 
Disagree, implementors need to see the member data, and it's handy to
have it at the top.
 
> 2) Private should come after public.
 
Disagree, at least for member data.
 
> 3) Your use of auto in a class interface is inappropriate; auto use at
> client site is fine but at API level it just obfuscates: what is the
> fucking return type?
 
Agree :-)
 
> 4) Your mixture of capital letter and underscores for class names is
> egregious.
 
Agree. Stroustrup once recommended this style, but I've never seen it used, and Stroustrup's latest style guide proposes PascalCase.
 
> 5) std::vector::at() can throw whilst std::vector::operator[] doesn't so
> it is confusing to mix the two as you are doing.
 
Agree.
 
> 6) Your use of inline keyword for in-class function declaration seems bogus.
 
Indeed. inline is unnecessary here.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 07 08:47PM +0100

On 07/07/2017 16:31, Gareth Owen wrote:
 
> Beside "convention", is there any reason for this rule?
 
> My tendency is to group public data and public functions together, so
> the user can see the whole API/contract/"interface" in one place.
 
Data does not form part of the interface because data that forms part of
the class invariant (that which the interface guarantees) cannot be public.
 
/Flibble
Daniel <danielaparker@gmail.com>: Jul 07 12:48PM -0700

On Friday, July 7, 2017 at 12:13:30 PM UTC-4, Alf P. Steinbach wrote:
> > bogus.
 
> And it tells you that, not as a hint that you'd have to figure out, but
> as absolutely required by the language rules,
 
But the compiler is free to ignore your inline declaration. It's still
only a hint.
 
Daniel
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 07 08:55PM +0100

On 07/07/2017 17:13, Alf P. Steinbach wrote:
> type. We don't care about the actual concrete iterator type: it can be
> whatever it is, and best if it automatically follows the container type
> and possible changes of constness of the member function and so on.
 
That is what typedefs are for:
 
{
private:
typedef vector<string> container_type;
public:
typedef container_type::const_iterator const_iterator;
public:
const_iterator begin() const { return items_.begin(); }
}
 
No longer brittle and now has value as it is obvious that begin()
returns an iterator of some sort so can be used where iterators are used
(e.g with <algorithm>). We indeed do not care what the actual concrete
iterator type is but we do care that it is an iterator.
 
 
> Then convenient range-checking can be provided at no cost, so it is. :)
 
> Since it's part of the interface (contract) of this class, it's in the
> interface, and it's hereby proved that that contract is noticed, thanks.
 
By convention operator[] doesn't throw whilst yours can so your
interface is broken, by convention.
 
> the definition, or both.
 
> Choosing to place it only on the definition would communicate the least,
> the minimum, to a reader of the code, opposite of what I want.
 
Nope. It's bogus.
 
/Flibble
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 10:12PM +0200

On 07-Jul-17 9:33 PM, Alf P. Steinbach wrote:
> On 07-Jul-17 8:38 PM, Manfred wrote:
[snip]
>> If you wish, your library could set up a decent argc/argv set from the
>> Windows command line,
 
> It does.
 
Oh, I was too hasty there, sorry.
 
But /now/ it does. :)
 
At least if this is what you were thinking of:
 
 
inline auto command_line() -> string;
 
class Command_line_args
{
protected:
vector<string> items_;
 
public:
auto begin() const { return items_.begin(); }
auto end() const { return items_.end(); }
 
auto size() const -> Size { return items_.size(); }
 
auto operator[]( Index const i ) const
-> ref_<const string>
{ return items_.at( i ); }
 
inline Command_line_args(); // Implemented for each
supported platform.
};
 
class Command_argv_array
: private Command_line_args
{
private:
vector<ptr_<char>> pointers_;
 
public:
auto argc() const -> int { return size(); }
auto argv() -> ptr_<ptr_<char>> { return &pointers_[0]; }
 
Command_argv_array( Command_line_args args = {} )
: Command_line_args{ move( args ) }
{
for( ref_<string> s : Command_line_args::items_ )
{
pointers_.push_back( &s[0] );
}
pointers_.push_back( nullptr );
}
};
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 10:17PM +0200

On 07-Jul-17 9:48 PM, Daniel wrote:
>> as absolutely required by the language rules,
 
> But the compiler is free to ignore your inline declaration. It's still
> only a hint.
 
No, it's absolutely required by the language rules.
 
The compiler is however, as I understand it, free to not diagnose the
resulting UB if one chooses to ignore the constraint.
 
C++14 §7.1.2/4:
 
"An inline function shall be defined in every translation unit in which
it is odr-used and shall have exactly the same definition in every case"
 
Note the "shall".
 
There is no wiggle room, it's an absolute requirement.
 
 
Cheers!, & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 10:22PM +0200

On 07-Jul-17 9:55 PM, Mr Flibble wrote:
 
> By convention operator[] doesn't throw whilst yours can so your
> interface is broken, by convention.
 
You mean that `operator[]` often has Undefined Behavior, in the
out-of-range cases where this interface has well-defined behavior.
 
Note that it's not guaranteed that it won't throw an exception for that UB.
 
The UB can do anything. ;-)
 
 
> [about something] Nope. It's bogus.
 
Well, I read that as the Fibble denial mode / entertainment trolling. No
offense intended. But otherwise I can't make sense of it.
 
 
Cheers!,
 
- Alf
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 07 09:27PM +0100

On 07/07/2017 21:22, Alf P. Steinbach wrote:
> out-of-range cases where this interface has well-defined behavior.
 
> Note that it's not guaranteed that it won't throw an exception for that UB.
 
> The UB can do anything. ;-)
 
You are missing the point. By convention I will assume it doesn't throw
so will have to write unnecessary bounds checking code and throw myself
when there is no need to.
 
 
>> [about something] Nope. It's bogus.
 
> Well, I read that as the Fibble denial mode / entertainment trolling. No
> offense intended. But otherwise I can't make sense of it.
 
Not trolling; your use of the keyword in class declaration is bogus.
 
I see you conveniently ignored my response re your egregious use of auto
keyword in an API? I will take that as acceptance that I am correct.
 
/Flibble
Manfred <noname@invalid.add>: Jul 07 10:37PM +0200

On 7/7/2017 9:33 PM, Alf P. Steinbach wrote:
> On 07-Jul-17 8:38 PM, Manfred wrote:
>> e.g. including wildchar expansion and the like.
 
> Yes, I've considered that, thanks!
[...]
> But doing that by default, as MinGW g++ unfortunately does for the
> arguments of `main`, breaks expectation in Windows: it does not conform
> to the convention established by the main compiler for the platform.
I am not that familiar with MinGW, but this probably follows from the
fact that such cmdline preprocessing has been designed to be performed
by the shell, and MinGW tries to emulate it, but it is a different thing.
> `fastmove` program that accepts `fastmove *.bah someplace\*.foo`. That
> will just not work with with MinGW g++'s default. And I don't know any
> way to tell MinGW g++ to not do that. :(
If MinGW manages to emulate the shell behaviour properly, then single or
double quoting ('*.bah') would do.
 
[...]
>> given the limited use of cmdline args on this platform.
 
> Command line args are used most every time you "open" a file in Windows,
> e.g. by double-clicking it.
Yes, but still much a more limited use of args, if compared to the other
environment.
 
[...]
 
> Well I meant the `command_line()` function to produce a possible command
> line that, when used to create a new process, would reproduce exactly
> the command line args here.
This seems to depend on the process creation API: in *nix the exec
family requires arguments specified by different string pointers, so no
quoting needed.
On Windows it depends on how CreateProcess handles the single
lpCommandLine string.
 
Ian Collins <ian-news@hotmail.com>: Jul 08 08:46AM +1200

On 07/ 8/17 01:26 AM, Mr Flibble wrote:
>> { return items_.at( i ); }
 
>> inline Command_line_args();
>> };
 
0) Use of "private:" here is superfluous.
 
 
--
Ian
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 11:23PM +0200

On 07-Jul-17 10:46 PM, Ian Collins wrote:
>>> {
>>> private:
 
> 0) Use of "private:" here is superfluous.
 
Generally, explicit is good, implicit is bad, except where you need a
choice to adapt automatically to changes.
 
As I understand it you would like to have an /implicit/ choice for the
access specifier where it can hurt (e.g., blind insertion of code can
break it) and where it doesn't reduce verbosity, and, judging from your
quote of Leigh's points, you would like to be /explicit/ about the
choice for iterator return type where that is needlessly constraining,
brittle and verbose; in both cases opposite of the code as given.
 
From my point of view that's a let's-adopt-anti-patterns! mindset.
 
 
Cheers!,
 
- Alf
Daniel <danielaparker@gmail.com>: Jul 07 02:25PM -0700

On Friday, July 7, 2017 at 4:18:23 PM UTC-4, Alf P. Steinbach wrote:
> it is odr-used and shall have exactly the same definition in every case"
 
> Note the "shall".
 
> There is no wiggle room, it's an absolute requirement.
 
Well, there's wiggling, and then there's wiggling. As I understand it, the
compiler is still free to generate a function call (as opposed substituting
inline substitution) to any function specified as inline, as long as the
rules regarding separate definitions in each translation unit are followed.
 
Daniel
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 07 11:47PM +0200

On 07-Jul-17 11:25 PM, Daniel wrote:
> compiler is still free to generate a function call (as opposed substituting
> inline substitution) to any function specified as inline, as long as the
> rules regarding separate definitions in each translation unit are followed.
 
Yes, the machine code inlining of calls effect of `inline` is just a hint.
 
The effect that I used `inline` for, quoted above, is not a hint, but an
absolute requirement, "shall".
 
It tells any reader of the code, when that reader is familiar with the
language rules, that the function must be or is defined as an `inline`
function, identically in every translation unit, which in practice means
in a header file, and that no linking with separately compiled stuff is
necessary for this function.
 
 
Cheers!,
 
- Alf
woodbrian77@gmail.com: Jul 07 07:25AM -0700

On Wednesday, July 5, 2017 at 4:01:52 AM UTC-5, peter koch wrote:
> Personally, I have much use of strings with a static maximum size, using them whenever I program against an interface which defines maximum sizes for I/O.
> This enables me to verify my strings size at creation rather than when I need to serialise it (putting it on a display or sending it over a wire).
 
> Internally, my size-limited strings are represented as a std::(w)string or as a boost::small_vector (if I remember the name correctly).
 
Thanks for the reminder of this class. By the grace
of G-d, I've now added support for small_vector to the
C++ Middleware Writer.
 
I wish this class was available more like plf::colony.
Colony is easy_to_work_with.
 
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
bitrex <bitrex@de.lete.earthlink.net>: Jul 07 10:37AM -0400

> helpful for cases that are bigger than that.
 
> Please let me know what you think about it. I may add some
> assignment operators.
 
I wrote something similar to that for use in embedded environments; it's
a little different in that my version uses a linked-list custom
allocator that plops std::strings (also using the allocator, allocating
blocks for characters within the blocks for whole strings) into a static
memory buffer that's created at startup. So say you can have a
"fixed_string<5, 60>" which will let you hold up to 5 strings of up to
60 characters each in memory that you can freely create, destroy, and
assign to each other cheaply (IIRC assignment is just moving a pointer
around) and do most of the usual string operations on without ever
needing to dynamically allocate memory from the heap
Robert Wessel <robertwessel2@yahoo.com>: Jul 06 07:52PM -0500

On Thu, 6 Jul 2017 15:16:35 -0700 (PDT), 嘱 Tiib <ootiib@hot.ee>
wrote:
 
>uninitialized buffer of bytes) are that it does not throw,
>and that with malloc the buffer may be further resized using realloc.
>These differences may give some benefit or not, it is always situational.
 
 
At least the first difference is usually eliminated by the use of the
nothrow variant of new.
"Öö Tiib" <ootiib@hot.ee>: Jul 06 05:11PM -0700

On Wednesday, 5 July 2017 09:23:50 UTC+3, Christiano wrote:
> p->insert(new Link{"Athena"});
> will not access any data from nullptr position (Insert will return on
> 2nd line).
 
The requirements to C++ language (standard) do not describe how the virtual
and non-virtual functions are implemented. Especially it nowhere mentions
"virtual table" nor that it is "data".
 
Can you give motivating example why would anyone want to call
non-virtual member functions for a bad pointer or nullptr (lets imagine
that it is defined behavior)?
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: