Saturday, June 27, 2015

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

woodbrian77@gmail.com: Jun 26 09:10PM -0700

> : string( s )
> {
> if( c > Capacity( 0 ) ) { reserve( static_cast<ptrdiff_t>( c ) ); }
 
I think I want a call to length in there:
 
reserve(length() + static_cast<ptrdiff_t>( c ) );
 
Im my example the length of "Usage: " was 7.
 
 
> auto main() -> int
> {
> cout << String( "123456789", Capacity( 30 ) ) << endl; // Output "12345678"
 
I think you dropped the 9 there. At least when I ran this on Linux
it output "123456789".
 
 
> }
 
> Due to the `enum class` the first output statement won't compile if you use `string` instead of `String`, thus avoiding that possible bug.
 
> Cheers & hth.,
 
Thanks a lot. It will help.

 
Brian
Ebenezer Enterprises - Bless G-d, America.
http://webEbenezer.net
legalize+jeeves@mail.xmission.com (Richard): Jun 27 04:37AM

[Please do not mail me a copy of your followup]
 
alf.p.steinbach@gmail.com spake the secret code
> #include <string>
> using namespace std;
 
> auto main() -> int
 
Again, gratuitous use of auto and ->.
 
> {
> cout << string( "123456789", 7 ) << endl; // Output "1234567"
> }
 
And here we have gratuitous (and purposeless) flushing of cout. Just
write '\n' instead of endl.
 
The purpose of endl is to emit an end-of-line character *and* flush
the buffer.
 
I routinely see people using endl all over the place when they only
intended to output '\n'.
 
In this case, the program is going to exit immediately after doing the
output and the buffer will automatically be flushed on exit, so the
use of endl is gratuitous.
 
Lest you think that such pickiness is pedantic, constantly flushing
cout when it isn't necessary causes a whole bunch of work to be
performed. cout is automatically tied to cin, so if you're thinking
you need to flush cout before obtaining input from cin -- so that a
user can see the prompt to a question before answering it -- this is
also unnecessary.
 
In short, endl is rarely needed in most programs, but it over-used in
almost all examples of C++. endl is only used by Stroustrup in "The
C++ Programming Language" when he gets to discussing manipulators of
IO streams. In the 3rd edition, this isn't until pg. 633! If you
look carefully at all his examples of text output to cout, it is all
done with \n and not endl. This is by design.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
alf.p.steinbach@gmail.com: Jun 27 07:12AM -0700

On Saturday, June 27, 2015 at 6:37:38 AM UTC+2, Richard wrote:
> > }
 
> And here we have gratuitous (and purposeless) flushing of cout. Just
> write '\n' instead of endl.
 
Thanks for these evaluations. As you can see from the posted code, they're not universally agreed on. If you want to convince people then I suggest posting some very clear rationale.
 
 
[snip explanations of basics]
> Lest you think that such pickiness is pedantic, constantly flushing
> cout when it isn't necessary causes a whole bunch of work to be
> performed.
 
The first rule of optimization is: MEASURE.
 
In the case of this program, the human mind is a good enough instrument.
 
I concluded that it ran fast enough. ;-)
 
That said, if you want i/o performance, then iostreams are generally a wrong and wrongheaded choice.
 
So, your argument is irrelevant for this example (do measure if you don't believe me), and it's also irrelevant in general, where one desires i/o performance.
 
 
[snip more explanations of basics]
 
Cheers & hth.,
 
-Alf
JiiPee <no@notvalid.com>: Jun 27 08:02PM +0100

On 27/06/2015 05:37, Richard wrote:
> IO streams. In the 3rd edition, this isn't until pg. 633! If you look
> carefully at all his examples of text output to cout, it is all done
> with \n and not endl. This is by design.
 
I am not sure how it should be currently, but just to mention that in
the famous book "The c++ standard library" Nicolaoi Josuttis seems to
always use std:end everywhere. So seems like there is no agreement what
is best...
 
Can anybody tell why would somebody want to flush the stream with end?
what is the benefit of that and in what situation? Can somebody show an
example where it would be beneficial?
woodbrian77@gmail.com: Jun 27 12:08PM -0700

> > cout when it isn't necessary causes a whole bunch of work to be
> > performed.
 
> The first rule of optimization is: MEASURE.
 
I agree with the gist of what you are saying, but would
say "measure" rather than shouting with caps.
 
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
woodbrian77@gmail.com: Jun 27 01:25PM -0700

> {
> cout << string( "123456789", 7 ) << endl; // Output "1234567"
> }
 
I'm sorry to hear that. Without checking into this, I
guess that constructor goes way back in string's history
and isn't something that was added years after string's
debut. I don't think I've ever seen that constructor
used anywhere but here.
 
I'm not sure what the options are, but if nothing else,
I'd be happy if a constructor based on an enum, like you
used, were be added to the class.
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
woodbrian77@gmail.com: Jun 27 01:47PM -0700


> I'm not sure what the options are, but if nothing else,
> I'd be happy if a constructor based on an enum, like you
> used, were be added to the class.
 
I want to take another shot at that paragraph:
 
I'm not sure what the options are, but if nothing else,
I'd like to see a constructor based on an enum, like you
used, added to the class.
 
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
Richard Damon <Richard@Damon-Family.org>: Jun 27 05:02PM -0400


> Brian
> Ebenezer Enterprises - In G-d we trust.
> http://webEbenezer.net
 
I think it is to convert a non-null terminated character array and make
it into a string. Note that I believe that this also allows you to
create a string with NULs in it.
 
string("123\0456") makes a string holding 3 characters.
string("123\0456", 7) put the whole string literal into the string.
alf.p.steinbach@gmail.com: Jun 27 02:19PM -0700

On Saturday, June 27, 2015 at 9:02:55 PM UTC+2, JiiPee wrote:
> the famous book "The c++ standard library" Nicolaoi Josuttis seems to
> always use std:end everywhere. So seems like there is no agreement what
> is best...
 
The benefits and drawbacks of endl versus "\n" are mostly insignificant, and they're open to interpretation.
 
For example, some may view it as a benefit that "\n" is not guaranteed to flush (though it may), because that can translate to marginally improved efficiency for non-console streams, while others may view the same feature as a drawback, because it means that when a crash occurs, one may not have all the information that one could have had -- some of it may reside in an output buffer.
 
And for example, some may view "\n" as more clear, while others may view endl as more clear.
 
 
> Can anybody tell why would somebody want to flush the stream with end?
> what is the benefit of that and in what situation? Can somebody show an
> example where it would be beneficial?
 
The flushing effect of std::endl is mostly just a convenience feature, to avoid having to do that via std::flush. I can't remember ever thinking of flushing when I've written "endl". For me it's more about a set convention, that when used consistently as a convention communicates clearly to the reader -- and writing code is more about communicating to humans than ordering the computer around. But I've also used the "\n" convention. I can't remember encountering the critical-info-lingering-in-buffer-on-crash scenario, but it's there as an argument -- but all of it, very vague, very insignificant, a matter of personal preference (what one deems most clear) unless coding guidelines on a project or in a company say otherwise.
 
Cheers & hth.,
 
- Alf
woodbrian77@gmail.com: Jun 27 02:47PM -0700

On Saturday, June 27, 2015 at 4:02:53 PM UTC-5, Richard Damon wrote:
> create a string with NULs in it.
 
> string("123\0456") makes a string holding 3 characters.
> string("123\0456", 7) put the whole string literal into the string.
 
::std::string aa("123\0456");
::std::string bb("123\0456",7);
::std::cout << "The len of aa is " << aa.size() << "\n";
::std::cout << "aa is " << aa << "\n";
::std::cout << "The len of bb is " << bb.size() << "\n";
 
The len of aa is 5
aa is 123%6
The len of bb is 7
 
I don't know what's happening with aa. Anyway, does anyone
use that constructor?
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
Richard Damon <Richard@Damon-Family.org>: Jun 27 05:11PM -0400

On 6/26/15 4:18 PM, JiiPee wrote:
> off what would be the difference than if I leave it there?
 
> No books/tutorials seem to explain this, they only explain the diamond
> formation.
 
The simplest case that show the difference is this:
 
class A
{
public:
int data;
}
 
class B : virtual public A
{
};
 
class C : virtual public A
{
};
 
class D : public B, C {
};
 
without the virtual, in the class D there are two different members
data, one in D::B::A and one in D::C::A. with the virtual, both B and C
will refer to the same sub-object A.
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jun 27 11:38PM +0200

> And so one in-practice effect is that the size of a B instance generally increases with use of virtual inheritance.
 
AFAIK this is just part of the vtable like the entry points for virtual
functions too. So as soon as you have at least one virtual function it
makes no difference in size anymore. And, well, it is quite likely to
have virtual functions when you need virtual inheritance.
 
Of course, none of the assumptions about sizeof are part of the
standard. They are only typical for common implementations.
 
 
Marcel
JiiPee <no@notvalid.com>: Jun 27 01:16AM +0100

On 26/06/2015 23:44, JiiPee wrote:
 
> How is is unsafe? I though int is in all system one byte integer,
> right? int choses automatically the faster integer type.
 
I forgot the minimum int size, its actually min 16 bit I think (not
always 32). So I guess to be portable with any system cannot use bigger
ints than that. Otherwise must use cstdint.
 
Although its quite rare a compiler would use 16 bit, right? VC++ uses 32
bit and I guess gcc as well.
 
Also I read that many prosessors are optimized for ints, so they run
fast(est) with int.
 
But you are right there can be risk, although maybe rare.
"If you want to you can statically (compile-time) assert the sizeof
these fundamental types. It will alert people to think about porting
your code if the sizeof assumptions change. "
 
So could check the size of the int to be sure the code works.
I dont know if I bother change my int-habit as it might make the code
more complex (as for example many library functions take int as an
parameter, so there would be integer conversions possibly). But sure
this risk must be taken into consideration.
 
>> there is a <cstdint> typedef for that.
 
> But if you chose the wrong one from there it would not be the fastest.
> int is always the fastest quaranteed
 
fastest for integers less than 4 bytes in most of the machines.
Bo Persson <bop@gmb.dk>: Jun 27 06:58AM +0200

On 2015-06-27 02:16, JiiPee wrote:
 
> I forgot the minimum int size, its actually min 16 bit I think (not
> always 32). So I guess to be portable with any system cannot use bigger
> ints than that. Otherwise must use cstdint.
 
No. What Mr Flibble wants to forget is that systems with 16 bit ints
will have lots of other limitations, like 640k of total RAM. Or no hard
disk.
 
Even if you use int32_t for your variables, an average program wouldn't
fit in available memory anyway. Or wouldn't run for other reasons. So
why bother?
 
 
Bo Persson
"Öö Tiib" <ootiib@hot.ee>: Jun 26 11:27PM -0700

On Saturday, 27 June 2015 00:37:40 UTC+3, Mr Flibble wrote:
 
> Because 'int' is both unsafe and non-portable. If you want the fastest
> integer that is at least a certain size then there is a <cstdint>
> typedef for that.
 
Isn't 'int' easier to read than 'int_fast16_t' of <cstdint>?
I don't think that latter is anyway safer or more portable than
former.
BGB <cr88192@hotmail.com>: Jun 27 01:28AM -0500

On 6/26/2015 11:58 PM, Bo Persson wrote:
 
> No. What Mr Flibble wants to forget is that systems with 16 bit ints
> will have lots of other limitations, like 640k of total RAM. Or no hard
> disk.
 
640kB is pretty massive as far as 16-bit systems go.
 
the PC was sort of an oddball in that it stayed 16-bit a little longer
than other systems, but had significantly more RAM than did most other
16-bit systems which have existed (or other computers which had existed
at the time).
 
 
and, to what extent 16-bit processors have lived on (such as in
microcontrollers), it has generally been with much smaller address
spaces than on the PC. (640kB of RAM would be huge by MCU standards...).
 
 
> Even if you use int32_t for your variables, an average program wouldn't
> fit in available memory anyway. Or wouldn't run for other reasons. So
> why bother?
 
yeah.
 
practically, 16-bit can mostly be ignored at this point.
 
if dealing with 16-bit DOS or Win16, there will be a lot bigger
funkiness to deal with than assumptions about "sizeof(int)" being wrong.
chances are, there will be some fairly specific reason for why code is
being targeted at these.
 
 
and if dealing with a microcontroller... chances are the code will be
written specifically for said microcontroller (there not being enough
RAM or ROM space to try to put any generic code on it, more likely the
code will need to be written specifically for that use-case).
jt@toerring.de (Jens Thoms Toerring): Jun 27 08:45AM


> Isn't 'int' easier to read than 'int_fast16_t' of <cstdint>?
> I don't think that latter is anyway safer or more portable than
> former.
 
Especially when some clever-san notices that he actually
can store values larger than 32767 in an int_fast16_t on
his machine. And, since he just learned from Mr Flibble
that the types from <cstdint> are safe and portable (in
contrast to this horribly unsafe and non-portable 'int'
type) concludes that this must work on all architectures
and is such a cute trick, saving lots of memory for sure!
And the cycles repeats again...
 
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
BGB <cr88192@hotmail.com>: Jun 27 09:01AM -0500

On 6/27/2015 8:46 AM, Stefan Ram wrote:
 
> Most problems with »template code bloat« arise from
> misunderstandings of template rules or improper use
> of templates.
 
errm, wasn't talking about templates, but using 'generic' in the general
sense, as-in, 'general purpose' code.
 
because of the typically small ROM space, most of the code needs to be
rather specific to the project.
 
 
it depends on the microcontroller though how much ROM space there is,
but typically it is in the kB range for 16-bit devices (32kB to 128kB is
fairly typical).
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 27 03:46PM +0100

On 27/06/2015 07:27, Öö Tiib wrote:
 
> Isn't 'int' easier to read than 'int_fast16_t' of <cstdint>?
> I don't think that latter is anyway safer or more portable than
> former.
 
Because use of the typedef means you are explicitly documenting in code
that the size of this type can vary and should be treated as such.
 
/Flibble
"Öö Tiib" <ootiib@hot.ee>: Jun 27 11:01AM -0700

On Saturday, 27 June 2015 17:06:08 UTC+3, BGB wrote:
> > of templates.
 
> errm, wasn't talking about templates, but using 'generic' in the general
> sense, as-in, 'general purpose' code.
 
Then it is straw-man in C++ sense. We lately tend to have all less and
less general purpose non-template code. Popular C++ libraries tend to
move towards templates and header only.
 
The ones that don't do it lose in popularity because of the unneeded
binary bloat, intrusive interface, not doing everything that is
possible compile-time and failing to generate competitive binaries.
 
The libraries that may survive that trend longer are in-house libraries
but those are not general purpose anyway.
 
 
> it depends on the microcontroller though how much ROM space there is,
> but typically it is in the kB range for 16-bit devices (32kB to 128kB is
> fairly typical).
 
If the controller has 2048 bytes of ROM or under then it does only
very few things. Even in assembler it can't take lot of weeks to
implement what it does. 32kB however can be quite lot of C++. Templates
(that is what we mean with "generic" in C++) are powerful tool on that
level.
"Öö Tiib" <ootiib@hot.ee>: Jun 27 02:17PM -0700

On Saturday, 27 June 2015 17:46:19 UTC+3, Mr Flibble wrote:
> > former.
 
> Because use of the typedef means you are explicitly documenting in code
> that the size of this type can vary and should be treated as such.
 
Maybe try to elaborate it bit more. What *is* the special treatment you
have in mind?
 
Usage of 'int', 'long', 'wchar_t', 'size_t', 'time_t', 'ptrdiff_t',
'fpos_t' (etc. just name it) in C or in C++ means that the byte size of
it may (and eventually will) vary per platform or next generation
of same platform. Also if two of above are exactly same type on current
platform then it is wrong to assume that these two are same on some other
platform (unlike 'int' and 'int_fast16_t' that must be are same in all
platforms where 'int_fast16_t' is defined). That all *must* be known of
course to everyone wanting to use C++ but what is the treatment?
 
Might be you expect too lot of the types of <cstdint>. Exact size of
type matters for example on case of binary exchange and storage formats.
Actually I don't know much other prominent cases. Are there any?
 
It may be that you currently deal with some such format ... but most
things are text these days like (JSON, XML or CSV). It is narrow
fraction of works where we want to squeeze last out and pick a binary
format.
 
Fixing physical byte size of types that participate in binary format
is unfortunately not the solution. Alignment and endianness are still
to be taken care of. Also since we took it for to squeeze everything
out of our bandwidth then why not to compress it even further? When
a value is in range 0..1000 then why not to use only 10 bits for it?
Well-made bit-packing can be faster than 'memcpy' on modern platforms
thanks to less cache misses.
 
A buffer of 'uint8_t' is therefore pretty much the best underlying
type for a portable binary format. Where 'uint8_t' exists at all there
it is precisely 'unsigned char' so 'uint8_t' can be considered just a
shorthand for 'unsigned char'.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 27 10:19PM +0100

On 27/06/2015 22:17, Öö Tiib wrote:
> type for a portable binary format. Where 'uint8_t' exists at all there
> it is precisely 'unsigned char' so 'uint8_t' can be considered just a
> shorthand for 'unsigned char'.
 
Because the size and value range of 'int' can vary from platform to
platform 'int' is inherently unsafe and non-portable. Use <cstdint>
typedefs instead.
 
/Flibble
"Öö Tiib" <ootiib@hot.ee>: Jun 27 09:58AM -0700

On Thursday, 25 June 2015 23:44:29 UTC+3, Robert Wessel wrote:
 
> What cases would exist where removing the "using namespace std;" isn't
> just going to result in obvious compilation errors for any references
> to things in std?
 
There are plenty of cases possible with big enough code written by
people who tend to maximize terseness. They like 'using namespace'
that may cause clashes. They like implicit conversions that sometimes
convert things in unintended ways. They also like short names that
are more likely to cause unexpected name clashes, name hiding or
function overloading.
 
After removal of "using namespace std;" it may happen that something
is converted to unintended thing or unintended overload is chosen or
any combination of those and there is a defect that does not manifest
itself compile time.
 
However the real problem is not some individual defect that was
caused by someone wrongly navigating in that fragile puzzle.
Why to waste man-years of maintenance works in context of minefield?
Just invest a week and remove the minefield. Even if some detonate
it is later lot cheaper to do the maintenance works.
ram@zedat.fu-berlin.de (Stefan Ram): Jun 27 01:46PM

>written specifically for said microcontroller (there not being enough
>RAM or ROM space to try to put any generic code on it
 
Templates that aren't used aren't instantiated.
Templates can thus generate less code than non-templates!
 
Most problems with »template code bloat« arise from
misunderstandings of template rules or improper use
of templates.
"Öö Tiib" <ootiib@hot.ee>: Jun 26 10:41PM -0700

On Friday, 26 June 2015 13:51:09 UTC+3, Chris Vine wrote:
> logic, the word "function" should be applied to functions which are
> referentially transparent and so analogous to mathematical functions
> and "procedure" to those which are intended to have side effects.
 
In C++14 we can mark at least some of the pure functions (as opposed
to subroutines that happen to have OUT parameter) with 'constexpr'.
 
> languages). It is conceptually indistinguishable from a function which
> returns void and transmits success or failure in some other way, such as
> by exceptions in C++.
 
Yes. In C++ we can indicate fatal failure with exception so we have less
need for such return values and for checking those.
 
> their practical expression in computer code - in any event "procedure"
> is the universally applied term in lisps). C++ certainly doesn't make a
> distinction.
 
Yes, but that does not matter if programming language makes distinction
or not. We are always far above of it. There are plenty of programming
languages that do not make distinction between immutable and mutable
objects or do not make distinction between virtual and non-virtual methods.
So what? Are these useless programming languages? No. The concepts are
still there, programmer just takes care if tool doesn't help.
 
So ... majority of objects are immutable and majority of methods are
non-virtual and the difference between function and procedure is still
like between noun and verb, regardless of programming language.
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: