- Double reference - 5 Updates
- neoGFX C++ ECS - 2 Updates
- sizeof(bitfield struct) - 8 Updates
- About Single Responsibility Principle - 9 Updates
- What does operating on raw bytes mean in a C++ context? - 1 Update
queequeg@trust.no1 (Queequeg): Nov 08 10:27AM >>Distribution through any means other than regular usenet > Sorry! I am using a new version of my Usenet client. > It seems to have copied some of the headers into the body. It didn't, your headers seem to be correct (and tin displays them correctly), although some lines in X-Copyright are indented with tab and some with spaces. RFC1036 says it's correct: The Internet convention of continuation header lines (beginning with a blank or tab) is allowed. -- https://www.youtube.com/watch?v=9lSzL1DqQn0 |
queequeg@trust.no1 (Queequeg): Nov 08 10:41AM > fn1(&iref, sizeof(int*)); > } > should work... But it's not the same. I modified it: #v+ void fn1(const void *p, size_t sz) { const unsigned char *b(static_cast<const unsigned char *>(p)); printf("Pointer value to be transferred:"); for (size_t i(0); i < sz; ++i) printf(" %02x", b[sz - i - 1]); printf("\n"); } void fn2(int &iref) { int *iptr(&iref); printf("Address of iptr: %p\n", &iptr); printf("Address of iref: %p\n", &iref); fn1(&iptr, sizeof(iptr)); fn1(&iref, sizeof(int*)); } int main() { int i(0x12345678); fn2(i); return 0; } #v- Running it gives: #v+ Address of iptr: 0x7eb0c574 Address of iref: 0x7eb0c584 Pointer value to be transferred: 7e b0 c5 84 Pointer value to be transferred: 12 34 56 78 #v- Addresses of iptr (temporary pointer) and reference (`i` in main) are different (and should be), but only the first call to fn1 (where it reads the temporary pointer) gives the proper address of `i` in main (address that is recreated in another thread). Reading data pointed to by &iref gives the value of `i` itself (which in this case is of the same size as the pointer-to-i). > In your fn2(), you are passing the address of the temporary _pointer_, > not the address of the pass-by-reference-variable, which seems wrong to > me. Instead it should be fn1(iptr, sizeof(iptr)). Hmm... I need to read the temporary pointer contents, that is -- know what it points to. After fn1() terminates, the pointer is not needed anymore, because its contents has been transferred. I don't want to transfer contents of `i`, I want to transfer its address. `i` is modified in `main` and I need to see these changes in thread. This is a simplified example, in reality `i` is not int, but a class. -- https://www.youtube.com/watch?v=9lSzL1DqQn0 |
queequeg@trust.no1 (Queequeg): Nov 08 10:56AM > You are not allowed to take the address of a temporary (an rvalue), so > yoy have to store the pointer somewhere first to get an lvalue. Like in > your example. Makes sense. Thanks! -- https://www.youtube.com/watch?v=9lSzL1DqQn0 |
Ralf Fassel <ralfixx@gmx.de>: Nov 08 04:24PM +0100 * queequeg@trust.no1 (Queequeg) | Ralf Fassel <ralfixx@gmx.de> wrote: | > void fn2(int &iref) | > { | > fn1(&iref, sizeof(int*)); | > } | > | > should work... | But it's not the same. Not the same as ... what? | void fn1(const void *p, size_t sz) | { | const unsigned char *b(static_cast<const unsigned char *>(p)); | printf("Pointer value to be transferred:"); | for (size_t i(0); i < sz; ++i) | printf(" %02x", b[sz - i - 1]); | printf("\n"); | } Why don't you simply use p here? printf("Pointer value to be transferred: %p\n", p); Why dereference it? Of course, if you dereference a pointer, you get the contents of what it points to, that's the nature of pointers... You're interested in the address of 'i' in main, correct? If so, just use that address! #include <cstdio> void f1(void *p) { printf("f1: address is %p\n", p); } void f2(int &num) { printf("f2: address is %p\n", &num); f1(&num); } int main() { int i; f1(&i); f2(i); } // g++ -o t t.cc // ./t // f1: address is 0x7ffff51fd61c // f2: address is 0x7ffff51fd61c // f1: address is 0x7ffff51fd61c HTH R' |
queequeg@trust.no1 (Queequeg): Nov 08 10:35PM > | > should work... > | But it's not the same. > Not the same as ... what? Not the same as reading the pointer value. fn1() will read data pointed to by &iref, which is the contents of the integer, not its address. > | } > Why don't you simply use p here? > printf("Pointer value to be transferred: %p\n", p); Still, because it's not the same as what this code does. In my simplified example this function just prints bytes to be transferred, real function encapsulates it and sends over a socket to another thread. > Why dereference it? Of course, if you dereference a pointer, you get > the contents of what it points to, that's the nature of pointers... I need exactly that. > f1(&i); > f2(i); > } Yes, with printfs it's simple, but how would you do it with write(), which expects an area of memory and its size (that's why fn1() expects the same)? -- https://www.youtube.com/watch?v=9lSzL1DqQn0 |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 08 11:27AM -0800 On Wednesday, November 7, 2018 at 2:18:13 PM UTC-5, Rick C. Hodgin wrote: > http://www.fox-toolkit.org/screenshots/iims3.png > Looks easy enough to code in, and plenty of built-in abilities, > not all of which are shown on those screenshots. Additional class information and documentation: http://fox-toolkit.org/ref/classes.html http://fox-toolkit.org/doc.html One of the best explanations I've ever seen of RegEx: http://fox-toolkit.org/rex.html -- Rick C. Hodgin |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 08 11:32AM -0800 On Thursday, November 8, 2018 at 2:28:05 PM UTC-5, Rick C. Hodgin wrote: > Additional class information and documentation: > http://fox-toolkit.org/ref/classes.html > http://fox-toolkit.org/doc.html Current class info (1.6): http://fox-toolkit.org/ref16/classes.html DEV class info: http://fox-toolkit.org/ref/classes.html > One of the best explanations I've ever seen of RegEx: > http://fox-toolkit.org/rex.html I post this information to give you some inspiration, Leigh. A lot of features packed into fox-toolkit, and they're free. Some thoughts from the author: Finally, I believe application developers will find the FOX library a more attractive alternative. For a software developer, the FOX Library is far more easy to learn, and offers some unique benefits, such as tying Widgets [Controls] together with little effort, being able to subclass from existing Widgets to make custom ones, and last but not least the ability to modify FOX's source code itself if necessary. FOX represents what I consider to be the ideal GUI Library; I wrote FOX to use it myself! -- Rick C. Hodgin |
Keith Thompson <kst-u@mib.org>: Nov 07 03:51PM -0800 David Brown <david.brown@hesbynett.no> writes: [...] > It is extremely simple to get the layout you want - use an appropriately > sized underlying type. (Yes, support for that is > implementation-dependant - but so are most things regarding bit-fields.) In C90, the only permitted underlying types for bit fields were int, signed int, and unsigned int, so it wasn't possible to use the underlying type to control the layout. (C99 added _Bool bit fields, and many implementations permit other integer types.) My understanding was always that defining unsigned int bf:5; simply meant that bf would occupy 5 bits and be able to store values in the range 0..31. Permitting, say, unsigned long or unsigned long long (as some C implementations do, and as C++ requires) means that you can have bit fields wider than an int, but it would never have occurred to me that changing the underlying type for the bit field itself would affect the layout of the structure outside the bit field. I understand and accept that it's conventional to use the underlying type that way, and I suppose I wouldn't object to a future C or C++ standard codifying that behavior, but I've always found it odd. If I wanted to control the layout in that manner, I'd probably find it clearer to add unused members after the bit field for padding. -- Keith Thompson (The_Other_Keith) kst@mib.org <http://www.ghoti.net/~kst> Will write code for food. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
David Brown <david.brown@hesbynett.no>: Nov 08 09:32AM +0100 On 08/11/18 00:51, Keith Thompson wrote: > int, signed int, and unsigned int, so it wasn't possible to use > the underlying type to control the layout. (C99 added _Bool bit > fields, and many implementations permit other integer types.) Yes, I realised that when someone else posted it. Many of the compilers I have used over the years have supported different bit-field types as extensions even in C90 modes - even some that had little or no C99 support. In my line of work, high portability is not often important, and use of compiler extensions are often required. (Plus my only copy of C90 is scanned pdf, so it is vastly easier to look things up in C99 or C11 standards and try to forget C90 ever existed...) > I understand and accept that it's conventional to use the underlying > type that way, and I suppose I wouldn't object to a future C or C++ > standard codifying that behavior, but I've always found it odd. Fair enough - I can understand that. Equally, I find it odd if the underlying type is /not/ used that way. I suspect this is a matter of what we are used to, what the tools we most use do, and where we use bit-fields. What is certain, is that bit-fields are not particularly portable. The semantics of them for storing data is of course portable, but the exact layout details is not. When you need exact layout to be portable, bit masks, shifts, and fixed-width integer types is the way to go. As I see it, there are three main uses of bit-fields. 1. For use within a program, to pack data more tightly. The exact layout details don't matter, and bit-fields work fine regardless of the rules used by the implementation. 2. For matching pre-defined data, such as in network protocols or file formats. Here you do need exact matching of layout, but access sizes don't matter. So if you have: struct X { uint32_t a : 5; uint32_t b : 7; uint32_t a : 4; } then you will need to know if X takes 2 bytes, 3 bytes or 4 bytes, and you need to know the endianness. But you don't care if reading "x.a" is done as an 8-bit read, a 16-bit read, or a 32-bit read (assuming there is valid memory after the X). And you'd be equally happy with "uint16_t" instead of "uint32_t" as the type. 3. For matching hardware registers, for device drivers or low-level embedded code. Here you need more - you are usually using volatile accesses, and if you say the bit-field type is "uint32_t" in X, then the compiler must generate a 32-bit read and write instruction and not 8-bit instructions. > If I wanted to control the layout in that manner, I'd probably find > it clearer to add unused members after the bit field for padding. Agreed. (I do that in normal structs too, and use -Wpadded in gcc to spot any missing padding. It is often not essential, but I like to have the padding explicit rather than implicit.) |
scott@slp53.sl.home (Scott Lurndal): Nov 08 01:59PM >accesses, and if you say the bit-field type is "uint32_t" in X, then the >compiler must generate a 32-bit read and write instruction and not 8-bit >instructions. For this, we generally use the following pattern (autogenerated from YAML description): #ifdef __cplusplus union register_name_t #else typedef union
Subscribe to:
Post Comments (Atom)
|
No comments:
Post a Comment