- #include'ing .c files considered harmful? - 12 Updates
- Onwards and upwards - 4 Updates
- gcc libatomic "sample library" - 1 Update
- New Python implementation - 6 Updates
- std::atomic<std::shared_ptr<T>>... - 1 Update
- Available C++ Libraries FAQ - 1 Update
mickspud@potatofield.co.uk: Feb 15 09:27AM On Sat, 13 Feb 2021 18:19:55 +0100 >> how you want padding if any. >No, it is not essential. It can be convenient, but it is far from the >only way to achieve the padding you want or to handle externally defined If you're creating the memory layout then put in whatever padding you want. >size. Non-aligned data can read or written using memcpy(), and good Yuck, very messy! But everyone has a prefered style I suppose. |
David Brown <david.brown@hesbynett.no>: Feb 15 10:47AM +0100 > If you're creating the memory layout then put in whatever padding you want. >> size. Non-aligned data can read or written using memcpy(), and good > Yuck, very messy! But everyone has a prefered style I suppose. memcpy can work simply and easily, it's portable, and with a good compiler it is usually optimally efficient with known fixed sizes. And it is always correct code, unlike some things people do with packed structs (like taking the address of non-aligned fields - something that may not work as expected). Any messiness can easily be wrapped in a C++ class or template - that's why you use C++. |
mickspud@potatofield.co.uk: Feb 15 10:03AM On Mon, 15 Feb 2021 10:47:39 +0100 >> Yuck, very messy! But everyone has a prefered style I suppose. >memcpy can work simply and easily, it's portable, and with a good >compiler it is usually optimally efficient with known fixed sizes. And No memcpy is going to be more efficient than a 1 line pointer cast which is all you need to do with mapping a structure onto a block of memory. Plus for any significant number of fields - eg for a TCP header with 9 fields - you going to have an equivalent number of memcpys in the code which frankly looks fugly and is much harder to visually parse. eg: tcp_hdr *thdr = (tcp_hdr *)packet; vs memcpy((char *)thdr.src,packet,2); memcpy((char *)thdr.dst,packet+2,2); memcpy((char *)thdr.seqnum,packet+4,4) etc etc Blech. No thanks. |
Manfred <noname@add.invalid>: Feb 12 05:15PM +0100 On 2/12/2021 9:25 AM, David Brown wrote: > ordering may affect the padding needed to ensure the correct alignments. > The alignment of the struct is the maximum of the alignments of the > members (or higher, if you use "alignas"). You are right that the standard does not relate alignment or padding with members order, and in fact gcc does not do that, thanks for pointing this out. However, from the MSVC docs: https://docs.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment?view=msvc-160#remarks "The compiler stores members after the first one on a boundary that's the smaller of either the size of the member type, or an N-byte boundary." https://docs.microsoft.com/en-us/cpp/preprocessor/pack?view=msvc-160#parameters "The alignment of a member is on a boundary that's either a multiple of n, or a multiple of the size of the member, whichever is smaller." So, this compiler /does/ padding between members depending on their order. |
David Brown <david.brown@hesbynett.no>: Feb 13 02:57PM +0100 On 12/02/2021 17:15, Manfred wrote: > "The alignment of a member is on a boundary that's either a multiple of > n, or a multiple of the size of the member, whichever is smaller." > So, this compiler /does/ padding between members depending on their order. As I said, the /padding/ between members in a struct does depend on their order. Their /alignment/ does not. That applies to MSVC, gcc, and any other compiler. If you have: struct S { char a; int b; char c; } where "int" is size 4 and alignment 4, then S will have an alignment of 4, there will be 3 bytes of padding between "a" and "b", and three bytes of padding after "c" - giving a total size of 12. If you arrange it as: struct S { char a; char c; int b; } then there will be 2 bytes of padding after "c", and a total size of 8 (with the same alignment of 4). If you arrange it as: struct S { int b; char a; char c; } then there will be 2 bytes of padding after "c" at the end of the structure, and a total size of 8 (with the same alignment of 4). Padding depends on the order, alignment does not. Now, compilers are free to /increase/ alignments if they want, and padding as needed to support that. It's not uncommon on 64-bit systems to use 8-bit alignment on structures, and data on stacks or in statically allocated memory can be given extra alignment - this can aid cache friendly memory layouts. And of course compilers can offer options or extensions to give different alignment (and thereby padding) arrangements, even if that breaks the platform's ABI. |
David Brown <david.brown@hesbynett.no>: Feb 15 12:35PM +0100 >> compiler it is usually optimally efficient with known fixed sizes. And > No memcpy is going to be more efficient than a 1 line pointer cast which is > all you need to do with mapping a structure onto a block of memory. Yes, it is - because the compiler knows what memcpy does, and can optimise appropriately. memcpy does not have to be implemented as an external library function call! #pragma pack(1) typedef struct S { int8_t a; int32_t b; int64_t c; } S; int getsize(void) { return sizeof(S); } int32_t getb1(const S* p) { return p->b; } int32_t getb2(const S* p) { int32_t x; memcpy(&x, &p->b, sizeof x); return x; } int32_t getb3(const S* p) { const uint8_t * q = (const uint8_t *) &p->b; int32_t x; uint8_t b[sizeof x]; for (size_t i = 0; i < sizeof x; i++) { b[i] = *q++; } memcpy(&x, b, sizeof x); return x; } gcc turns all of these into a single "mov" instruction. Modern compilers (and many old ones) can do a lot of nice things in their optimisation. Standard library functions are specified in the standard, and the compiler can take advantage of that. > memcpy((char *)thdr.seqnum,packet+4,4) > etc etc > Blech. No thanks. You already have to handle accessing these with the right endianness. You can't just read the fields and use the values. (Well, you can if you have a compiler with extensions that cover endian specifications and those are used in the struct definition - but that is far from standard.) |
James Kuyper <jameskuyper@alumni.caltech.edu>: Feb 15 08:43AM -0500 > On Mon, 15 Feb 2021 10:47:39 +0100 > David Brown <david.brown@hesbynett.no> wrote: ... >> compiler it is usually optimally efficient with known fixed sizes. And > No memcpy is going to be more efficient than a 1 line pointer cast which is > all you need to do with mapping a structure onto a block of memory. He said "optimally efficient", not "more efficient". What he's suggesting is that a compiler could easily optimize a call to memcpy() into exactly the same machine code that would be generated for the code you describe. > memcpy((char *)thdr.src,packet,2); > memcpy((char *)thdr.dst,packet+2,2); > memcpy((char *)thdr.seqnum,packet+4,4) Why the (char*) casts? memcpy() takes void*, which can be implicitly converted to from any object pointer type, which is the only reason why the char* cast works. A direct conversion to void* is no less safe than an indirect one using char* as an intermediate step. |
mickspud@potatofield.co.uk: Feb 15 03:31PM On Mon, 15 Feb 2021 12:35:10 +0100 >Yes, it is - because the compiler knows what memcpy does, and can >optimise appropriately. memcpy does not have to be implemented as an >external library function call! So what? 9 memcpys will be a min of 9 mov's at best. 1 cast is 1 mov though potentially zero depending on how smart the compiler is. >> Blech. No thanks. >You already have to handle accessing these with the right endianness. So what? You'd have to call ntoh*() or similar after the fact regardless of what method you used. I suppose you could write your own endian aware memcpy for numeric values but why bother plus its unlikely to be very efficient. |
mickspud@potatofield.co.uk: Feb 15 03:33PM On Mon, 15 Feb 2021 08:43:31 -0500 >suggesting is that a compiler could easily optimize a call to memcpy() >into exactly the same machine code that would be generated for the code >you describe. No it wouldn't. Maybe for 1 but not for 9. >> memcpy((char *)thdr.dst,packet+2,2); >> memcpy((char *)thdr.seqnum,packet+4,4) >Why the (char*) casts? memcpy() takes void*, which can be implicitly Habit. Plus I forgot &. |
David Brown <david.brown@hesbynett.no>: Feb 15 05:55PM +0100 >> external library function call! > So what? 9 memcpys will be a min of 9 mov's at best. 1 cast is 1 mov > though potentially zero depending on how smart the compiler is. Casts frequently don't need any instructions - pointer casts on most systems are free at run time. /Accessing/ the data takes instructions. The point is that with a good enough compiler (and sensible flags), memcpy is going to give you the same code. The key difference is that casting pointer types then using them to access data is often lying to the compiler - for all but a handful of exceptions, it is behaviour undefined by the standard. This means you can easily get something that works fine in your simple tests, but fails in more complex situations when code is inlined, link-time optimised, or otherwise used in more advanced code. Memcpy, on the other hand, is well specified and safe. > So what? You'd have to call ntoh*() or similar after the fact regardless of > what method you used. I suppose you could write your own endian aware memcpy > for numeric values but why bother plus its unlikely to be very efficient. The point is that you have to have code for accessing the fields, you can't just use them directly. And when you have a an accessor function anyway, you might as well write it correctly, safely and portably - it will be just as efficient. I am not at all suggesting that memcpy is always the best way to write code - merely that it is not an expensive way to do it either in terms of run-time costs or in source code clarity, and it is often safer and more portable. People have been writing code to access network-defined or file format defined structures since C has been in existence, and #pragma pack is neither necessary nor sufficient for the task. |
David Brown <david.brown@hesbynett.no>: Feb 15 05:57PM +0100 >> into exactly the same machine code that would be generated for the code >> you describe. > No it wouldn't. Maybe for 1 but not for 9. I think you are misunderstanding something here. If you read three items view a pointer, you will (in general) have a minimum of three read instructions. If you do it with three optimised memcpy() calls, you also have three read instructions. The code is the same. |
mickspud@potatofield.co.uk: Feb 15 05:16PM On Mon, 15 Feb 2021 17:55:58 +0100 >memcpy is going to give you the same code. >The key difference is that casting pointer types then using them to >access data is often lying to the compiler - for all but a handful of Sorry? Its standard C. Perhaps its frowned on in C++ but I've been doing network programming for a couple of decades and this method is used all over the place. No one does 50 memcpys if there's a memory structure with 50 fields in it just for the sake of ivory tower correctness, you'd have to be insane. A structure only has to be correct once in the header, memcpys have to be correct everywhere you use them. If you don't believe me have a look in any of the /usr/include/linux network header files and then go through this and check out the casting to structs: https://github.com/torvalds/linux/blob/master/net/ipv4/tcp.c >exceptions, it is behaviour undefined by the standard. This means you >can easily get something that works fine in your simple tests, but fails >in more complex situations when code is inlined, link-time optimised, or Rubbish. Maybe in Windows but that doesn't concern me. >> for numeric values but why bother plus its unlikely to be very efficient. >The point is that you have to have code for accessing the fields, you >can't just use them directly. And when you have a an accessor function Wtf are you taking about? You just access them as structure fields. There may be a small cost in deferencing but there's a large gain in code readability and correctness. >more portable. People have been writing code to access network-defined >or file format defined structures since C has been in existence, and >#pragma pack is neither necessary nor sufficient for the task. Whether its pragma pack or attribute packed, its used a lot in Linux. $ pwd /usr/include/linux $ grep __attribute__ *.h | grep packed | wc -l 239 But what do they know? |
David Brown <david.brown@hesbynett.no>: Feb 15 01:15AM +0100 On 14/02/2021 23:56, Brian Wood wrote: >> checked by no one is merely part of the daily grind for a coder. > Perhaps we can at least agree that services are the most important > form of software today Absolutely not, no. I don't really think it makes sense to talk about "the impost important form of software" - our way of life depends on a wide variety of software types. But if I had to pick one, it would be embedded software - the kind that most people never see, and never think about, but makes things work. Online code generators would rank down at the bottom of the list - they are not necessary in any way. They might sometimes be convenient, but they are not important. > and that C++ is the most important language > for services. Again, no. Most online services are written in other languages. C++ is not the worst choice (it's far better than C) for that kind of thing, but it is not a great choice either. >> harder sell for most potential code reviewers. > A lot of code review is done for free: > https://www.reddit.com/r/codereview Sure - for free projects. No one does code reviews for free for commercial products. Why do you think people should review /your/ code for free? > for articles of silver and gold, and for clothing. And the L-RD gave the > people such favor in the sight of the Egyptians that they granted their > request. In this way they plundered the Egyptians." Exodus 12:36,37 I'm sorry, I can't see what relevance there is in quoting an old story book. > The Israelites didn't pay for the items of gold and silver. G-d was > saving them from their oppressors. Unfortunately, some of the > regulars here are oppressors. No one here is oppressing /people/ - certainly not oppressing Christians, Jews, Israelites, Egyptians, or any other particular religion or nationality. People /do/ oppress preaching or pointless, off-topic and repetitive religious posts. Stick to the topic at hand. |
Brian Wood <woodbrian77@gmail.com>: Feb 14 06:16PM -0800 On Sunday, February 14, 2021 at 6:15:57 PM UTC-6, David Brown wrote: > Again, no. Most online services are written in other languages. C++ is > not the worst choice (it's far better than C) for that kind of thing, > but it is not a great choice either. At least you didn't say Scala or Ada or some other nonsense. > Sure - for free projects. No one does code reviews for free for > commercial products. Why do you think people should review /your/ code > for free? My software is free -- like duckduckgo.com. > Christians, Jews, Israelites, Egyptians, or any other particular > religion or nationality. People /do/ oppress preaching or pointless, > off-topic and repetitive religious posts. Stick to the topic at hand. This reminds me of Don Cheadle's comment that cancel culture is "not really real." https://www.dailywire.com/news/don-cheadle-cancel-culture-is-not-really-real The topic is about how to improve my repo: https://github.com/Ebenezer-group/onwards and website: https://webEbenezer.net . Brian |
David Brown <david.brown@hesbynett.no>: Feb 15 09:02AM +0100 On 15/02/2021 03:16, Brian Wood wrote: >> not the worst choice (it's far better than C) for that kind of thing, >> but it is not a great choice either. > At least you didn't say Scala or Ada or some other nonsense. Are you just picking random programming languages that you personally don't like? Different languages are suitable for different purposes - Ada and Scala have their place. C++ covers an unusually broad range of tasks, probably broader than any other language. But that doesn't mean it is the appropriate choice for all tasks. When I write online services (these are not public services), I don't use C++ - I use Python. Others use other languages, including some using C++. (A very quick and rough way to gauge the choice of language for online services would be to look at the Wikipedia page for "Comparison of web frameworks". Look at how many of these are written in the various languages - that will give you an idea of what people think is the right language for a task like that.) >> commercial products. Why do you think people should review /your/ code >> for free? > My software is free -- like duckduckgo.com. Your software is commercial, as far as I can see. Some of it is open source, but parts of it are closed source and your intention is to get paid for that software - it's part of your company business plan. (There's nothing wrong with that - people are free to choose what they give away and what they don't, and if you spend your time creating a worthwhile product or service, then it's natural to get paid for the effort.) However, there /is/ something wrong with asking others to work for you for free so that you stand a better chance of earning money with the software. > This reminds me of Don Cheadle's comment that cancel > culture is "not really real." > https://www.dailywire.com/news/don-cheadle-cancel-culture-is-not-really-real I don't know or care who that person might be, and we were not discussing "cancel culture" - real, imaginary, under-estimated or over-blown as it may be. It is this kind of rambling that makes it less likely for anyone to want to be connected with you. > The topic is about how to improve my repo: > https://github.com/Ebenezer-group/onwards First you have to give people a reason to help. > and website: > https://webEbenezer.net I can give you good advice here, but you are not going to like it. It is, however, a genuine recommendation of what would help your company. Find someone who is able to run a company, and pay them to fix yours. Pay someone to make you a website that looks like it is the site of a company. Get someone to put relevant information on the website, and remove the begging and pleading, and the irrelevant links (especially the antisocial ones). In general, you have to decide if you are a programmer, or a failed project manager and company owner. If you want your "CMW" to succeed as a project, find someone who can manage the project. If you want your company to succeed, find someone to run it. I'm sure you can do the programming fine, but that's not the main ability if you want to make a living from your software. Damn few people can manage to handle both roles well, and it's not easy (ask Jacob Navia how much free time he gets). |
"Öö Tiib" <ootiib@hot.ee>: Feb 15 03:45AM -0800 On Monday, 15 February 2021 at 10:02:34 UTC+2, David Brown wrote: > I can give you good advice here, but you are not going to like it. It > is, however, a genuine recommendation of what would help your company. By "Parable of the Sower" <https://en.wikipedia.org/wiki/Parable_of_the_Sower> you are knowingly sowing into thorns. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Feb 13 01:36PM -0800 On 2/13/2021 4:51 AM, Bonita Montero wrote: >> - Raw spin locks make no sense on /any/ single core. > Raw spinlocks almost never make sense in userland. True. |
mickspud@potatofield.co.uk: Feb 15 09:34AM On Sat, 13 Feb 2021 12:52:50 -0800 >> process couldn't accomplish. If you know otherwise then feel free to explain. >IOCP is basically windows version of POSIX aio. Just make sure to never >create a process and/or thread per connection. That really, really bad. I guess that depends on how long many connections you're expecting per unit time, how long they stay up and how important the server is. I wrote a middleware system that forked every time a new connection came but but we only expected a few connections a minute and they'd stay up for 2-3 mins at a time. Plus it was a critical system and if the main process went down the company backend would grind to a halt so multiplexing and threading were off the table. |
mickspud@potatofield.co.uk: Feb 12 03:26PM On Fri, 12 Feb 2021 14:52:01 +0000 >> execution structures as procedural languages. If you knew anything about >> parsing you'd know that. >Why do you assume that I have no knowledge regarding declarative languages? Do Because you pretend you have a lot of knowledge about a lot of things but when pressed you tend to come up short and resort to... >you often make such assumptions when interacting with people you know fuck all >about and their projects that you know fuck all about? ..answering questions with a question just like a 2nd rate politician. So lets see an example of your wonder compiler compiling some SQL, Prolog or other declarative language. I mean since its a universal compiler you'd have done that, right? >> can't? >I am not in the habit of teaching ignorant, presumptive, arrogant cockwombles >the fundamentals, dear. Another of your standard responses when you can't answer. But thanks for playing son. |
Mr Flibble <flibble@i42.REMOVETHISBIT.co.uk>: Feb 12 04:04PM >> Why do you assume that I have no knowledge regarding declarative languages? Do > Because you pretend you have a lot of knowledge about a lot of things but > when pressed you tend to come up short and resort to... Assertions made without evidence can be dismissed with evidence. > So lets see an example of your wonder compiler compiling some SQL, Prolog or > other declarative language. I mean since its a universal compiler you'd have > done that, right? Since when is SQL ever "compiled"? >> the fundamentals, dear. > Another of your standard responses when you can't answer. But thanks for > playing son. I don't believe I have ever responded with those exact words before, dear, ergo it cannot be one of my "standard" responses. If you want to learn about threads then I suggest you go back to school, dear. /Flibble -- 😎 |
mickspud@potatofield.co.uk: Feb 12 05:12PM On Fri, 12 Feb 2021 16:33:09 +0000 >On 12/02/2021 16:20, mickspud@potatofield.co.uk wrote: Still waiting for your proof. Take your time. >It is "UNIX" not "unix", dear. And as far as UNIX-like is concerned: Linux's >overcommit/OOM-killer to support fork()ing is a fucking omnishambles; but you >wouldn't know this of course as you are fucking clueless anachronism. Oh dear, someone tell the child about copy-on-write. If you're going to google stuff and pretend its your own knowledge you might want to have a clue first. FWIW overcommit is pretty standard amongst OS's of all colours and has been for decades. >If you knew anything useful about threads you would know what advantages they >have over processes; I repeat: go back to school, dear. Thanks for proving my point. Have a good w/e with your boyfriend cupcake. |
mickspud@potatofield.co.uk: Feb 12 04:20PM On Fri, 12 Feb 2021 16:04:05 +0000 >> Because you pretend you have a lot of knowledge about a lot of things but >> when pressed you tend to come up short and resort to... >Assertions made without evidence can be dismissed with evidence. So prove me wrong. >> other declarative language. I mean since its a universal compiler you'd have >> done that, right? >Since when is SQL ever "compiled"? Oh I dunno, probably since the 1980s. Or do you think RDBMs store procedures as plain text then parse them each time? >I don't believe I have ever responded with those exact words before, dear, >ergo it cannot be one of my "standard" responses. >If you want to learn about threads then I suggest you go back to school, dear. I've been fully versed in threads for 2 decades buttercup and I've yet to see anything they can do that multiprocess can't though mileage may vary for each depending on the use case. However I'm speaking from a unix POV. I guess if you've only programmed on a toy OS like Windows that can even do something as fundamental as multiplexing network sockets without threading then I guess you may well be screwed without them. |
Mr Flibble <flibble@i42.REMOVETHISBIT.co.uk>: Feb 12 04:33PM > if you've only programmed on a toy OS like Windows that can even do something > as fundamental as multiplexing network sockets without threading then I guess > you may well be screwed without them. It is "UNIX" not "unix", dear. And as far as UNIX-like is concerned: Linux's overcommit/OOM-killer to support fork()ing is a fucking omnishambles; but you wouldn't know this of course as you are fucking clueless anachronism. If you knew anything useful about threads you would know what advantages they have over processes; I repeat: go back to school, dear. /Flibble -- 😎 |
"Öö Tiib" <ootiib@hot.ee>: Feb 14 03:36PM -0800 On Monday, 15 February 2021 at 00:05:41 UTC+2, Chris M. Thomasson wrote: > extended until the temporary std::shared_ptr is destroyed as well. > ___________________ > Does shared_ptr have a "separate" reference count to weak_ptr's? Yes. |
Nikki Locke <nikki@trumphurst.com>: Feb 14 11:23PM Available C++ Libraries FAQ URL: http://www.trumphurst.com/cpplibs/ This is a searchable list of libraries and utilities (both free and commercial) available to C++ programmers. If you know of a library which is not in the list, why not fill in the form at http://www.trumphurst.com/cpplibs/cppsub.php Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website. |
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