Saturday, April 30, 2016

Digest for comp.lang.c++@googlegroups.com - 6 updates in 3 topics

Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Apr 30 11:00PM +0100

On Sat, 30 Apr 2016 23:50:06 +0200
> theoretically possible. However, you might find that many compilers
> that have sizeof(long) == 1 and CHAR_BIT == 32, don't support long
> long...
 
You are learning too many lessons from Jerry about bogus straw man
arguments. Leaving aside long long, I agree with you, as you will see if
you re-read my posting about systems where all integer types are 32 bit.
 
C requires long long (if supported) to be 64 bits. So for that, his
test would work, in any case where all integer types are not 64 bit,
and as you say I do not know of any.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 30 11:22PM +0100


> It wouldn't have, but on the 16-bit point he could have just substituted
> long for short and his test would work: C (and C++) require long to be
> 32 bits,
 
C requires long to be at least 32 bits (and I presume C++ is similar).
Some of the TI processors have a 40-bit integer type and if an
implementation used that underlying type for long you'd run into the
other issue with padding bits (where c[0] might correspond to bits that
don't contribute to the value of the long).
 
So what's the best way round these issues? Usually you could justify
simply ignoring such odd cases. But to get the most widely portable
solution I'd advise (a) use unsigned types everywhere; (c) use (as you
suggest) unsigned long; (b) set the value the other way round by setting
the representation; (d) print the resulting value so you can pick up odd
cases like the PDP-11's mixed endian byte order:
 
union {
unsigned long value;
unsigned char bytes[sizeof(unsigned long)];
} u;
for (int i = 0; i < sizeof u.bytes; i++)
u.bytes[i] = i + 1;
printf("ORDER_%lx_ENDIAN\n", u.value);
 
You get a more complicated result, but the code that uses it will, most
likely, just use it to reject all the odd cases. If your code depends
on endianess, you probably did not code it to handle 40-bit integers
with 3 16-bit bytes anyway!
 
The above will still go wrong if unsigned long has padding bits and the
resulting bit pattern turns out to be a trap representation. The other
version also suffers from that problem but this one avoids false
positives caused by padding bits.
 
If you have C99 or C11, there's an argument for using unsigned long long
or even uint_max_t rather than unsigned long.
 
<snip>
--
Ben.
David Brown <david.brown@hesbynett.no>: Apr 30 11:57PM +0200

On 30/04/16 23:36, Chris Vine wrote:
> shell command for the purpose.
 
> His solution was unix specific and (so far as concerns the -D option)
> dependent on a compiler such as gcc or clang which supports it.
 
Yes, I noticed that after my post. It is still system dependent - it's
just an attempt at being smart-ass about generating configuration files
automatically. If you know you have gcc, you can use its macros
directly. If you know you have glibc, you can use #include <endian.h>.
I'm sure posix defines a header somewhere containing endian macros.
When you know the details of the system, it's easy - the challenge was
to have a completely implementation-independent solution.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Apr 30 11:59PM +0100

On Sat, 30 Apr 2016 23:22:13 +0100
> positives caused by padding bits.
 
> If you have C99 or C11, there's an argument for using unsigned long
> long or even uint_max_t rather than unsigned long.
 
Jerry's code provides a larger test type (short in his case but we are
now supposing long), and an array of char of size sizeof(short) - or
sizeof(long) in our supposed case. Sizes of integers must be multiples
of sizeof(char), so it seems to me to be highly improbable that padding
is an issue.
 
I am not an expert of C11 but it seems to me that C11 probably requires
Jerry's scheme to work (C89 does not, nor does C++). §6.2.6.1/7 of C11
provides that "When a value is stored in a member of an object of union
type, the bytes of the object representation that do not correspond to
that member but do correspond to other members take unspecified
values". In the case in question the array of char and the larger
integer type do have the same number of bytes so there are no
unspecified values. But maybe padding is allowed to alter this, I
don't know. The original defect report for C89 leading to C99 said "To
address the issue about "type punning", attach a new footnote 78a to
the words "named member" in 6.5.2.3#3: 78a If the member used to access
the contents of a union object is not the same as the member last used
to store a value in the object, the appropriate part of the object
representation of the value is reinterpreted as an object
representation in the new type as described in 6.2.6 (a process
sometimes called "type punning"). This might be a trap
representation." I am not sure if C11 still permits a trap
representation in this case (see §6.2.6.1/6). If you say it does in
order to permit padding, I will believe you.
 
If it does, there is unspecified behaviour rather than undefined
behaviour. gcc's specified behaviour is to permit type punning of this
kind via unions, and I suspect the same is true of most other compilers
as it is a very common idiom.
 
Chris
Juha Nieminen <nospam@thanks.invalid>: Apr 30 09:40AM


> void foo(char (&a)[4]) {}
 
> 'a' retains its quality as a reference to an array of char of size 4,
> and it will refuse to compile if passed a char array of any other size.
 
It is actually a very useful feature. It's how eg. std::end() and
range-based for loops for static arrays work. They are sometimes
useful for all kinds of things in templated code.
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
"Chris M. Thomasson" <nospam@nospam.no>: Apr 30 12:45AM -0700


> FWIW, some, IMHO, fairly interesting C++ code for Field Based DLA:
 
> https://plus.google.com/101799841244447089430/posts/am5EpMHcmig
 
> https://github.com/ChrisMThomasson/CT_fieldDLA
 
[...]
 
BTW, if you have any questions about the code,
please ask them. I think we can make this
algorithm much more efficient, humm...
 
https://github.com/ChrisMThomasson/CT_fieldDLA/blob/master/cairo_test_penrose/ct_field.hpp
 
The (ct::field::search_hit) function can be
improved, along with (ct::field::calc_point).
These are very important "hot spots" in the
(ct::field::render) function.
 
If you are interested, and think this is off topic,
we can move it to:
 
https://plus.google.com/101799841244447089430/posts/DfjAJbbdLGp
 
However, it is C++ with Cairo and GLM, not that bad
for third part libs...
 
If I confine posts to this thread only, is it okay to post updates here?
 
;^o
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: