- Available C++ Libraries FAQ - 1 Update
- Stored in Big Endian. . . . . . inside Little Endian - 4 Updates
- Wikipedia article "false sharing" - 1 Update
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. |
Siri Cruise <chine.bleu@yahoo.com>: Feb 13 06:10PM -0800 In article <d8ea59a5-9f2a-4a26-92fb-184469ec8181n@googlegroups.com>, > the integer variable "s_addr". I checked the Linux manual and it says that > 's_addr' is always in Network Byte Order (i.e. Big Endian), even on modern > desktop PC's running MS-Windows which are all Little Endian. Once upon a time there were functions like ntohs, htons, etc for converted bytes in network order to host order and vice versa [wike wersa] for various size ints. They were also useful for things like binary files: choose network or host order for external media and use these. Then you never have to worry about 'endianness'. Just consistently use network or host order. -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @ 'I desire mercy, not sacrifice.' /|\ Discordia: not just a religion but also a parody. This post / \ I am an Andrea Chen sockpuppet. insults Islam. Mohammed |
James Kuyper <jameskuyper@alumni.caltech.edu>: Feb 14 02:54AM -0500 On 2/13/23 15:22, Chris Vine wrote: > On a point not relating to your question about endiannes, C++ being what it is this appears to have undefined behaviour. This is not because it breaches the strict aliasing rules (it doesn't by virtue of [basic.lval]/11), but because of the rules on pointer arithmetic. > This is because the array subscript operator implies arithmetic: according to [expr.sub]/1 "the expression E1[E2] is identical (by definition) to *((E1)+(E2))". However, pointer arithmetic is only allowed on pointers pointing into arrays, and only within the range of the array, unless E1 is a null pointer and E2 is 0 ([expr.add]/4). Here, s_addr is required to be composed of contiguous bytes but this may take the form of a 32-bit scalar rather than formally of an array of unsigned char meeting the definition in [dcl.array]. > This seems an oversight in the C++ standard, or at least poor drafting of [expr.add]/4 with respect to its spraying about of undefined behaviour on pointer arithmetic. Leaving aside endianness, this usage is reasonable, is widely employed in practice and has defined behaviour in C. The up side is that it seems highly improbable that any compiler is going to do other than what you expect. "For any object (other than a potentially-overlapping subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes (6.7.1) making up the object can be copied into an array of char, unsigned char, or std::byte (17.2.1).36" 6.8p2. The "36" at the end of that citation references footnote 36, which says: "By using, for example, the library functions (16.5.1.2) std::memcpy or std::memmove." I think it's clear that s_addr has a trivially copyable type. Note that it does not say that those functions are the only ones that could be used, only that they are examples of how it could be done. I take that to mean that any code which has defined behavior equivalent to that of std::memcpy() could also be used. The behavior of std::memcpy() is not defined in the C++ standard itself, but only by cross-reference to the definition of memcpy() in the C standard: "The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1." (C standard, 7.24.2.1p2). I therefore conclude that any user-defined function with the same argument list as memcpy() which contained the obvious implementation of that function would also be allowed. Keep in mind that memcpy() has no ways of knowing what the actual type of the data it is accessing is - it takes a const void* argument. And that implies that it is safe to access those bytes as characters, even if you don't copy them. |
Chris Vine <vine24683579@gmail.com>: Feb 14 03:57AM -0800 On Tuesday, 14 February 2023 at 07:54:41 UTC, James Kuyper wrote: > ways of knowing what the actual type of the data it is accessing is - it > takes a const void* argument. And that implies that it is safe to access > those bytes as characters, even if you don't copy them. It is true that [intro.object]/8 provides that "an object of trivially copyable or standard-layout type (6.8) shall occupy contiguous bytes of storage", and [basic.types]/2 provides that in the case of a trivially copyable type such contiguous bytes may be copied by memcpy(), but I don't agree that the fact that the C++ standard imports memcpy() from C in order to do so means that pointer arithmetic necessary to implement a user-side version of the function is automatically validated. You could view memcpy() as a built-in black box which the compiler must in some way known only to itself provide in order to comply with [basic.types]/2. But we don't need to argue about that because I think that you can implement memcpy() in C++ by relying on the fact that any single object (including any individual byte) can be treated as an array of one element for pointer arithmetic purposes ([basic.compound]/3), so you can validly increment a pointer to any one byte to one past the byte, which in the case of the contiguous bytes of a trivially copyable type will also be a pointer to the next byte, and progress in that way. So the OP's example could it seems to me, by making the pointer non-const, have been written in a way compliant with [expr.add]/4 as: cout << static_cast<unsigned>(*p++) << "." << static_cast<unsigned>(*p++) << "." << static_cast<unsigned>(*p++) << "." << static_cast<unsigned>(*p++); But this does not mean that expressions like (p+2) or (p-1) are valid in C++. It seems to me to be unarguable that those fail to comply with [expr.add]/4 except where p points into an actual array and the result is within its range. This means that for example various byte swapping idioms for scalars common in C are not valid in C++. That seems to me to be a fault with the C++ standard. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Feb 14 06:15PM -0500 On 2/14/23 06:57, Chris Vine wrote: > On Tuesday, 14 February 2023 at 07:54:41 UTC, James Kuyper wrote: ... >> The "36" at the end of that citation references footnote 36, which says: >> "By using, for example, the library functions (16.5.1.2) std::memcpy >> or std::memmove." ... > is automatically validated. You could view memcpy() as a built-in > black box which the compiler must in some way known only to itself > provide in order to comply with [basic.types]/2. If that were the case, the normative text would mandate the use of std::memcpy() or std::memmove(). It doesn't. It merely specifies "the underlying bytes (6.7.1) making up the object can be copied into an array of char, unsigned char, or std::byte", without specifying the methods that can be used to achieve that result. memcpy and memmove are mentioned only non-normatively as ways that you could cause such a copy to occur, without specifying that they are the only ways. > byte, which in the case of the contiguous bytes of a trivially > copyable type will also be a pointer to the next byte, and progress in > that way. I don't agree that this is necessary in order for the code to have well-defined behavior. However, since memcpy() and memmove() can be implemented using exclusively increment or decrement operations, and the same can be done in user code, I don't see this as an argument preventing user code from copying the object byte-by-byte. |
Bonita Montero <Bonita.Montero@gmail.com>: Feb 14 06:35PM +0100 What do you think about the false sharing code I've added to https://en.wikipedia.org/wiki/False_sharing under "Example". |
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