- Zeroing in the constructor - 10 Updates
- About virtual inheritance - 2 Updates
- Avoid 'int', 'long' and 'short'... - 10 Updates
- "C++11/14/17 Features In VS 2015 RTM" - 1 Update
- Avoid 'int', 'long' and 'short'... - 1 Update
- Ugly code to solve a combinatorial problem with an integer sum - 1 Update
| 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:
Post a Comment