Thursday, November 8, 2018

Digest for comp.lang.c++@googlegroups.com - 25 updates in 5 topics

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

No comments: