- confusion about function "template" within a template class of another typename - 2 Updates
- issues with std::variant - 3 Updates
- enum type in template declaration - 3 Updates
- two's complement idea - 2 Updates
- What does the "L" mean - 9 Updates
- "Microsoft Exploring Rust as the Solution for Safe Software" - 2 Updates
Soviet_Mario <SovietMario@CCCP.MIR>: Dec 07 09:06PM +0100 I fork here because this doubt about template is different from the enum thread I don't know how to code this situation, so I try to write broken pseudocode that does not compile, hoping to be able to explain better than with plain words .... I have this situation 'tt' will be either double or FixedString (a fast wasty string class for strings up to a maximum size which inside has an "embedded" fixed array and an used field for shorter strings to be copied for the exact extent, they are asciiZ '\0' terminated for support of std functions) template <typename tt> class Table { tt Dati [constMaxRighe] [constMaxColonne]; template <typename xx> Table <xx> ExtractSubTable \ (int * SelectedRowList, int * SelectedColumnList, \ int numRows, int numCols); } now assume that ExtractSubTable must exist in 4 specializations from Table <double> to Table <double> from Table <double> to Table <FixedString> from Table <FixedString> to Table <double> from Table <FixedString> to Table <FixedString> assume also I would declare and define the body outside the class header (it will be big) is it possible to code the function ONCE and not four times ? Overloaded operators are just defined for every possible double <=> FixedString combinations, so a single generic function could (I hope and guess) be coded once. I am confused as how to declare it .... template <typename tt> \ template <typename xx> Table <xx> \ Table <tt> :: ExtractSubTable \ (int * SelectedRowList, int * SelectedColumnList, \ int numRows, int numCols) { int TgtRow, TgtCol; Table <xx> RetVal; for (int Row = 0; Row < numRows; Row++) { tgtRow = SelectedRowList [Row]; for (int Col = 0; Col < numCols; Col++) { tgtCol = SelectedColList [Col]; // will operator = be chosen properly ? RetVal.Dati [Row] [Col] = Dati [tgtRow] [tgtCol]; } } } the declarators is tempted completely random, please explain me the order of nesting, or even if a multiple template (I believe not) like template <tt, xx> is due and also, how to generate the four specialized ExtractSubTable functions ? I am confused in nested templates; tnx How to produce all four -- 1) Resistere, resistere, resistere. 2) Se tutti pagano le tasse, le tasse le pagano tutti Soviet_Mario - (aka Gatto_Vizzato) |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 08 12:30AM +0200 On 7.12.2019 22:06, Soviet_Mario wrote: > strings up to a maximum size which inside has an "embedded" fixed array > and an used field for shorter strings to be copied for the exact extent, > they are asciiZ '\0' terminated for support of std functions) So, reinventing std::string. Why? > template <typename xx> Table <xx> ExtractSubTable \ > (int * SelectedRowList, int * SelectedColumnList, \ > int numRows, int numCols); What's this obsession with backslashes and line continuation? It's not needed beyond macro definitions. > from Table <double> to Table <FixedString> > from Table <FixedString> to Table <double> > from Table <FixedString> to Table <FixedString> So, every FixedString will be convertible to double? What happens if it is an empty string or "abc"? If it is restricted to be numeric why don't you hold everything in double? > assume also I would declare and define the body outside the class > header (it will be big) No, it will not be big, It will be two lines: 1. Extract subtable of the same type (one function call) 2. Convert it into the needed type (second function call). This is called modular design. The functions implementing those two lines might be larger, but the result will be less complex than your design which attempts to do two things at once. When you have got this working and the customer is not satisfied with the performance, then you might need to look into ways how to improve it. Note that it is not given that the your solution to do two things at once in a function is the best solution. > template <typename xx> Table <xx> \ > Table <tt> :: ExtractSubTable \ > (int * SelectedRowList, int * SelectedColumnList, \ Weird backslash obsession again... |
"Öö Tiib" <ootiib@hot.ee>: Dec 07 04:43AM -0800 On Friday, 6 December 2019 19:44:14 UTC+2, Taylor wrote: > > rawly newed pointer to document then said that it is wrong and used > > the most dork tool std::make_shared! I stopped right there. > You should continue watching. He's just using shared_ptr in his example. Huh? Each shared_ptr usage is dynamic allocation of sole object plus complicating your data from tree to directed acyclic or may be even introducing directed cycles into your data. Additionally it is rather expensive (in both performance and storage usage) smart pointer. It has usages but rare or else you turn your program into as error prone and inefficient mess as typical Java or C# programs are. So video where you are casting it into code without apparently no thought applied is not worth watching. It proves that you are either snake oil salesman or noob. > A production implementation would use a small-object optimization. In fact, central to his type erasure scheme is reducing the amount of dynamic allocation. Blah blah blah blah? If something can't be written as document then it is *never* worth watching as video either. I have already posted link to document and open source implementation of one way how to reduce dynamic allocations: <https://www.boost.org/doc/libs/1_71_0/doc/html/poly_collection.html> C++ is powerful so there are several other ways and each can be used and discussed in separation or in combination. |
Manfred <noname@add.invalid>: Dec 07 06:17PM +0100 On 12/7/2019 1:43 PM, Öö Tiib wrote: > complicating your data from tree to directed acyclic or may be even > introducing directed cycles into your data. Additionally it is rather > expensive (in both performance and storage usage) smart pointer. The point about shared_ptr in the video is that the speaker starts presenting a use of shared_ptr, then he shows how bad it is and replaces it for a while with unique_ptr. However, in the end he resumes the use of shared_ptr, but only as pointer to const, as a mean to reduce copies. So it is less stupid than you posed it. That said, I don't like shared_ptr either. It > has usages but rare or else you turn your program into as error prone > and inefficient mess as typical Java or C# programs are. Totally agree on this. |
"Öö Tiib" <ootiib@hot.ee>: Dec 07 11:45AM -0800 On Saturday, 7 December 2019 19:17:57 UTC+2, Manfred wrote: > The point about shared_ptr in the video is that the speaker starts > presenting a use of shared_ptr, then he shows how bad it is and replaces > it for a while with unique_ptr. Does not matter. Usage of shared_ptr is often outright defect. Usage of lot of single object allocations/deallocations is not defect (but usually weak design). > However, in the end he resumes the use > of shared_ptr, but only as pointer to const, as a mean to reduce copies. > So it is less stupid than you posed it. Ok, I agree, not so utterly stupid. Making the shared objects immutable makes it at least valid to process our now directed acyclic data in embarrassingly parallel manner. So we at least can burden all the cores (or even GPUs in our typical target architecture) next to effortlessly when needed. But the prices of dynamic memory management per object, overhead from expensive pointer, incapability to realize that equivalent immutable object that we are creating now is already shared elsewhere and additional trouble during serialization still remain. I by default resolve those proactively by having special (smart) factory and special (smart) pointers but shared_ptr can also be good enough when used like that. However when data logically really has directed cycles in it (that happens ultra rarely) then I use likes of Parallel BGL. <https://www.boost.org/doc/libs/1_71_0/libs/graph_parallel/doc/html/index.html> At least some hope that someone else is testing it too. > > has usages but rare or else you turn your program into as error prone > > and inefficient mess as typical Java or C# programs are. > Totally agree on this. So I'm just bit allergic to it. The unreliable stuff that has resulted from misuse of shared_ptr IMHO keeps damaging reputation of C++. Unsure what book taught to put it everywhere ... it should be burnt. |
saturnman2008@gmail.com: Dec 07 01:53AM -0800 在 2019年12月6日星期五 UTC+8上午6:21:05,Soviet_Mario写道: > enum class RestrictedValues { A = 1, B = 2, C = 4, D = 8 }; > template <RestrictedValues ttVal> class SizedField > { public: static constexpr int aSize = static_cast<int>(ttVal); > The goal is to have a template depending on a restricted > well defined, and known at compile time, set of integral values > enum RestrictedValues { A = 1, B = 2, C = 4, D = 8 }; template <RestrictedValues ttVal> class SizedField { private: unsigned char zzArray [ttVal]; public: etc etc } > 1) Resistere, resistere, resistere. > 2) Se tutti pagano le tasse, le tasse le pagano tutti > Soviet_Mario - (aka Gatto_Vizzato) If my modification fits your requirement? |
Soviet_Mario <SovietMario@CCCP.MIR>: Dec 07 06:54PM +0100 Il 06/12/19 23:51, Paavo Helde ha scritto: > be known at compile time. And vice versa, if something is > only known only at run-time, you have to do it in an > old-fashioned run-time way - an if, a switch, etc. yes, in fact the template function which cannot solve one aspect, has a switch. But the control variable of the switch must be evaluated by ITS TYPE (or some internal ID, hash or other info associated to the type, not its value). In other words it must emulate sort of a virtual function selector. Many other aspect of the generic container using a lot of common operators with a homogeneous semantic (assignments, overloaded by both, comparisons, idem) are instead managed by the container generically. Indexing like an array but using operator () (row, column) instead is semantically different for container<double> and container<fixed_string>, the specialized versions do not have even the same number of parameters, the latter has a third parameter for index of character I cannot explain well :\ anyway yes, there are lots of aspects of templates I miss to understand -- 1) Resistere, resistere, resistere. 2) Se tutti pagano le tasse, le tasse le pagano tutti Soviet_Mario - (aka Gatto_Vizzato) |
Soviet_Mario <SovietMario@CCCP.MIR>: Dec 07 06:57PM +0100 > static constexpr int aSize = static_cast<int>(ttVal); >> private: >> unsigned char zzArray [aSize]; Yes it was a slight of mine to not have converted an enum to int explicitely. But the main question was not about that. Anyway they have just reassured me that the compiler checks for invalid non-forced cast in the reverse sense (from a generic integer to the enum) in the specialization of an instance. That was the source of my concern. The forced manual cast did not worry me, I try not to shoot in my foot :) -- 1) Resistere, resistere, resistere. 2) Se tutti pagano le tasse, le tasse le pagano tutti Soviet_Mario - (aka Gatto_Vizzato) |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Dec 07 07:53AM -0800 > can't have two libraries that both define `ONESCOMPLEMENT`. Perhaps > library A defines it as above but library B defines it to produce a > one's complement. A macro may be defined in places other than public libraries. Or if it is defined in a public library, and a possible ambiguity is important to remove, it's easy enough to prefix the macro name with the namespace used for the library. Would you have the same objection to using a macro if the macro were not defined in a public library? > Perhaps both define it as above but using library B you get a > redefinition warning. I don't know why you think that. Giving several identical definitions for a macro is allowed in C90, C99, C11, C++98, C++03, C++11, C++14, and C++17. Testing with gcc, clang, g++, and clang++ gave no diagnostics even with -Wall and -Wextra. > And for example, regarding the so far not mentioned visual > impact, the shouting uppercase is an annoying eyesore. But that has nothing to do with the macro processor. You are perfectly free to choose a name that is not all uppercase, or even all lowercase, if you'd rather. What you said might be an argument about how to name a macro but it is not an argument about whether to use a macro. Taking all of these together, the objections given sound more like rationalizations trying to justify an overarching dislike of macros than objectively reasoned conclusions. |
"Öö Tiib" <ootiib@hot.ee>: Dec 07 08:22AM -0800 On Saturday, 7 December 2019 17:53:56 UTC+2, Tim Rentsch wrote: > with the namespace used for the library. Would you have the same > objection to using a macro if the macro were not defined in a > public library? The authors of libraries are often competitors and so do not like that you pick and integrate best of breed from their products. The bigger ones seemingly even enjoy introducing such conflicts and contradictions. Sometimes even with standard library. Anyone targeting Windows had sooner or later to look up what to do with min and max macros in windows.h. > definitions for a macro is allowed in C90, C99, C11, C++98, > C++03, C++11, C++14, and C++17. Testing with gcc, clang, g++, > and clang++ gave no diagnostics even with -Wall and -Wextra. Libraries next to never define macro identical to letter and so tests show opposite: <http://coliru.stacked-crooked.com/a/65fc657ef88c80fa> What you suggest to do with these annoying warnings? Silence? Branch library code? Get the authors to cooperate? > even all lowercase, if you'd rather. What you said might be an > argument about how to name a macro but it is not an argument > about whether to use a macro. I agree. We can just configure our tools and text editors to show macros with different color if we for some reason want these to stand out visually at all. However lot of coding standards have those rules in and so majority of macros that we face are in SCREAMING_CAPS. > Taking all of these together, the objections given sound more > like rationalizations trying to justify an overarching dislike of > macros than objectively reasoned conclusions. Sure, if you dismiss all problems (that we have tired of facing in practice) with claim that those do not exist then answering to your question why we avoid macros is impossible. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Dec 07 03:55AM Vir Campestris <vir.campestris@invalid.invalid> writes: <cut> >>>> <cut> >>>>> The one that really strained C was the one where incrementing a >>>>> pointer by 1 went to the next bit. Not byte or word. (TI GPU) <cut> > BTW the Dec10 - the 36 bit one I used - an int was 36 bits, but a > character string was stored as set of 5 7-bit ASCII characters plus > one pad bit in each word... Never used C on it though. It would be very expensive to implement C using that packed format for character strings. Some C implementations on other word addressed machines decided to make char one word; on others arithmetic was needed to convert between word and "char" pointers. It's notable that, programmer assumptions aside, word addressed machines are probably more awkward for C the bit-addressed ones. -- Ben. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Dec 06 11:38PM -0500 On 12/6/19 10:55 PM, Ben Bacarisse wrote: > Vir Campestris <vir.campestris@invalid.invalid> writes: ... > to convert between word and "char" pointers. It's notable that, > programmer assumptions aside, word addressed machines are probably more > awkward for C the bit-addressed ones. I can't vouch for this from personal experience, but I remember being informed by others in this newsgroup that the byte size was configurable on that machine. 5 7-bit bytes was just one option. 4 9-bit bytes was another, and somewhat less expensive than using an entire word to store a character. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Dec 06 10:20PM -0800 > bit. Other values are available :( [...] > The one with 36 bits (DECSystem10) an address was the address of a > word, and you couldn't point to a character inside the word. The PDP-10 did have a format, and instructions that used that format, to access any contiguous set of bits within a 36-bit word. They were called, IIRC, byte pointers, and would serve perfectly well as a representation for 'char *' and 'void *'. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Dec 06 10:36PM -0800 > to convert between word and "char" pointers. It's notable that, > programmer assumptions aside, word addressed machines are probably more > awkward for C the bit-addressed ones. The PDP-10 had a special representation for pointing to, and accessing, "bytes" within a word, and instructions for doing loads, stores, and pointer arithmetic in terms of "bytes" rather than words. A nice thing about the PDP-10 byte pointers is the width in bits of a "byte" is part of the stored representation in each byte pointer. A C implementation on a PDP-10 could choose 9-bit bytes for 'char' without too much trouble[*]. Alternatively, for a bit of fun, bytes could be 12 bits, with two bytes for int's, and three bytes for long (no longer works for C11, naturally), and two 36-bit words for long long. But 9-bit bytes would work just fine, even for C11. (Sorry folks - no uint32_t in those implementations.) [*] IIRC, "bytes" in the PDP-10 were treated as unsigned, so signed types would need sign extension on loading. |
boltar@nowhere.co.uk: Dec 07 11:57AM On Fri, 6 Dec 2019 17:50:39 +0000 >type in calculations? >If you need to use a format code (I don't know how much that is still >prevalent in C++), is it %d, %ld or %lld? I still use printf, cout is bloody awful for simple text formatting. I've seen multiple lines of setfill, setwidth etc loads of times, all of which could have been done with something like a 20 char printf format. But yes, officially you need to know the size of what you're passing to printf (and scanf) so it outputs correctly, though given both are built into the compiler I imagine the compiler could be a bit smart about it and promote/demote as appropriate but I don't know how often thats done, if ever. >> Sorted. >You use a library where the author also 'sorted' by using a type 'mylong'. stdint.h is an official standard header file and has been for decades. |
Bart <bc@freeuk.com>: Dec 07 12:04PM >>> Sorted. >> You use a library where the author also 'sorted' by using a type 'mylong'. > stdint.h is an official standard header file and has been for decades. Sorry, I thought from the names used in your examples that you were typedef-ing myint and mylong, rather than declaring instances with those names. In that case, you don't know whether your typedef-ed 'mylong' is going to be defined on top of the same ?intN_t types as someone else's 'mylong'. |
boltar@nowhere.co.uk: Dec 07 01:05PM On Sat, 7 Dec 2019 12:04:15 +0000 >names. >In that case, you don't know whether your typedef-ed 'mylong' is going >to be defined on top of the same ?intN_t types as someone else's 'mylong'. Eh? If you want to be sure of the size of an int or long just use the official typedefs for 32 and 64 bit types. I don't see what the problem is. |
Bart <bc@freeuk.com>: Dec 07 01:16PM > Eh? > If you want to be sure of the size of an int or long just use the official > typedefs for 32 and 64 bit types. I don't see what the problem is. Yeah, /I/ can do that. The problem is not everyone else will do so. Is int64_t* the same as long*? Sometimes yes, sometimes no, sometimes it depends. Is a 1234L constant equivalent to int64_t, or int32_t? Messy, but I was originally replying to this comment: [PH:] "As a result, now they [MS] cannot change 'long' to 64-bit because they have abused it so much." As I said, at least on Windows, you know it will be 32-bits. |
"Öö Tiib" <ootiib@hot.ee>: Dec 07 05:49AM -0800 On Saturday, 7 December 2019 15:16:38 UTC+2, Bart wrote: > > If you want to be sure of the size of an int or long just use the official > > typedefs for 32 and 64 bit types. I don't see what the problem is. > Yeah, /I/ can do that. The problem is not everyone else will do so. That is the problem of those others who do not use official typedefs. Why it is problem of yours? > Is int64_t* the same as long*? Sometimes yes, sometimes no, sometimes it > depends. If it somehow matters use std::is_same_v<int64_t*,long*>, it is compile time bool. But I don't use long* in my code anywhere so it does not matter. > Is a 1234L constant equivalent to int64_t, or int32_t? Same there. I don't use any longs in code and I don't use L suffixes to integer literals. As result it is problem of those others who do it wrong. > [PH:] "As a result, now they [MS] cannot change 'long' to 64-bit because > they have abused it so much." > As I said, at least on Windows, you know it will be 32-bits. Where Windows API has long in interface? Signed 32 bit integers seem everywhere to be LONG or INT32 in it. So user can use conversions to those (often nop conversions) where integrating with Windows API. Everywhere else it does not matter. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Dec 06 10:12PM -0800 > "Microsoft Exploring Rust as the Solution for Safe Software" > https://www.infoq.com/news/2019/11/microsoft-exploring-rust-safety/ > I doubt it. Repeating a similar comment made in another posting, I propose a rule of thumb for postings like this one: unless a posting is likely to generate a substantial fraction of responses that are simultaneously of interest in both comp.lang.c and comp.lang.c++, it should be multi-posted rather than cross-posted (specifically for c.l.c and c.l.c++). |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 07 07:28AM +0100 > simultaneously of interest in both comp.lang.c and comp.lang.c++, > it should be multi-posted rather than cross-posted (specifically > for c.l.c and c.l.c++). The article is related to C as well as C++-programmers. Multiposting is therefore stupid here. |
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