- Avoid 'int', 'long' and 'short'... - 3 Updates
- Ugly code to solve a combinatorial problem with an integer sum - 2 Updates
- About virtual inheritance - 4 Updates
- Zeroing in the constructor - 1 Update
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 26 10:37PM +0100 On 26/06/2015 21:31, JiiPee wrote: >> /Flibble > you mean using int16_t? why is that? > int is the fastest integer so why would i use something else? 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. /Flibble |
JiiPee <no@notvalid.com>: Jun 26 11:44PM +0100 On 26/06/2015 22:37, Mr Flibble wrote: >> you mean using int16_t? why is that? >> int is the fastest integer so why would i use something else? > Because 'int' is both unsafe and non-portable. How is is unsafe? I though int is in all system one byte integer, right? int choses automatically the faster integer type. > If you want the fastest integer that is at least a certain size then > 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 |
Ian Collins <ian-news@hotmail.com>: Jun 27 11:02AM +1200 JiiPee wrote: >> Because 'int' is both unsafe and non-portable. > How is is unsafe? I though int is in all system one byte integer, right? > int choses automatically the faster integer type. Please, not again! We've already had this thread... -- Ian Collins |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 26 10:36PM +0100 > Using a macro symbol to choose between two possibilities in such example code is perfectly OK. No it isn't; macros should be avoided. How is a newbie supposed to know that you didn't mean to use macros when you used macros? >> different translation units then your program is exhibiting undefined >> behaviour as you are breaking the ODR rule. > Example code that demonstrates a feature is usually (and in this case) very different from production code. Macros are bad, period, be it example code or production code. > Cheers & hth., > - Alf (as you can see, accessing this group via GG I do see your postings). Trollololol. /Flibble |
Ian Collins <ian-news@hotmail.com>: Jun 27 11:01AM +1200 Mr Flibble wrote: >> Using a macro symbol to choose between two possibilities in such example code is perfectly OK. > No it isn't; macros should be avoided. How is a newbie supposed to know > that you didn't mean to use macros when you used macros? So all of your system and standard library headers are bad code? -- Ian Collins |
JiiPee <no@notvalid.com>: Jun 26 09:18PM +0100 Everybody knows that with diamond inheritance we need virtual inheritance. But what does virtual inheritance do really (for one class)? like if i have: class A { public: int data; }; class B : virtual public A { public: int data2; }; class C : public B {}; So what difference "virtual" makes here to class B? if I take virtual 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. |
alf.p.steinbach@gmail.com: Jun 26 02:00PM -0700 On Friday, June 26, 2015 at 10:18:39 PM UTC+2, 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. Each ordinary inheritance of A adds a distinct A sub-objects, but all virtual inheritances of A together add just a single A sub-object. And this means that if there is more than one B base class sub-object, they must have the A sub-object at different offsets. In practice this means that each instance of B must contains some information that says at what offset the virtually inherited A sub-object is for this instance. And so one in-practice effect is that the size of a B instance generally increases with use of virtual inheritance. It might be possible for the compiler to tuck the offset information in somewhere unused, but generally you do get a size increase: struct A { int data; }; struct Bnv: public A { int data2; }; struct Bv: virtual A { int data2; }; #include <iostream> auto main() -> int { using namespace std; cout << sizeof( Bnv ) << " " << sizeof( Bv ) << endl; } MinGW g++ 5.1 (64-bit) reports 8 16 and Visual C++ 2015 (32-bit) reports 8 12. The offset information has to be used at run time, and this means that unless one has an unusually smart compiler, referencing A sub-object data members will be somewhat less efficient with virtual inheritance. Also, B's constructors may in practice have to support possible future inheritance from B, where it's a requirement that initialization of the virtual inheritance A sub-object from B is ignored, that instead it must be initialized from the most derived class. So there's decision overhead too. Although I suspect it's so marginal that it won't show up in ordinary measurements. * * * Summing up, in general you have a size increase, and in general somewhat less efficient access of the virtually inherited A sub-object's data items. Cheers & hth., - Alf |
JiiPee <no@notvalid.com>: Jun 26 10:09PM +0100 On 26/06/2015 21:35, Marcel Mueller wrote: > Only if the class tree contains more than one A base, then virtual > will force them to share one instance of A. If there is only one link > to A it make no difference, of course. oh ok, then this is clear. Funny they do not explain this, as it leaves the theory open. so it has only an effect if there is 2 (or more). I think they should mention this in books. |
JiiPee <no@notvalid.com>: Jun 26 11:42PM +0100 > Each ordinary inheritance of A adds a distinct A sub-objects, but all virtual inheritances of A together add just a single A sub-object. And this means that if there is more than one B base class sub-object, they must have the A sub-object at different offsets. ok this answers the question. I was meant to ask more like : in what situation we would use virtual inheritance like this. obviously I would not use it if not needed. But that answers the question. |
alf.p.steinbach@gmail.com: Jun 26 02:29PM -0700 > "Usage: "). That would avoid having to make more allocations > for the pieces as they are added and copying after the allocations. > I'm hoping this will make it into std::string implementations. Yeah, it would be a nice feature. Your proposed constructor signature is however already taken: #include <iostream> #include <string> using namespace std; auto main() -> int { cout << string( "123456789", 7 ) << endl; // Output "1234567" } But you can do this: #include <iostream> #include <string> #include <stddef.h> using namespace std; enum class Capacity: ptrdiff_t {}; struct String : string { using string::string; String( char const* const s, Capacity const c = Capacity( 0 ) ) : string( s ) { if( c > Capacity( 0 ) ) { reserve( static_cast<ptrdiff_t>( c ) ); } } }; auto main() -> int { cout << String( "123456789", Capacity( 30 ) ) << endl; // Output "12345678" cout << String( 30, '-' ) << endl; } 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., - Alf |
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