Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #75624 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-11-10 09:10 -0800 |
| Last post | 2015-11-10 10:50 -0800 |
| Articles | 20 on this page of 184 — 23 participants |
Back to article view | Back to comp.lang.c
Objective C Alla _ <modelling.data@gmail.com> - 2015-11-10 09:10 -0800
Re: Objective C "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-10 09:16 -0800
Re: Objective C Richard Heathfield <rjh@cpax.org.uk> - 2015-11-10 17:17 +0000
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-10 09:32 -0800
Re: Objective C Mark Storkamp <mstorkamp@yahoo.com> - 2015-11-10 11:38 -0600
Re: Objective C James Kuyper <jameskuyper@verizon.net> - 2015-11-10 12:36 -0500
Re: Objective C Alla _ <modelling.data@gmail.com> - 2015-11-10 11:15 -0800
Re: Objective C Richard Heathfield <rjh@cpax.org.uk> - 2015-11-10 21:51 +0000
Re: Objective C Alla _ <modelling.data@gmail.com> - 2015-11-10 23:13 -0800
Re: Objective C supercat@casperkitty.com - 2015-11-13 16:01 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-14 01:07 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-14 06:26 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-14 22:22 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-14 15:46 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-15 01:47 +0000
Re: Objective C BartC <bc@freeuk.com> - 2015-11-15 10:43 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-15 13:19 -0800
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-14 15:43 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-15 23:50 +0100
Re: Objective C gazelle@shell.xmission.com (Kenny McCormack) - 2015-11-16 00:05 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-15 19:10 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-16 09:11 +0100
Re: Objective C supercat@casperkitty.com - 2015-11-16 11:57 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-16 20:38 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-16 13:20 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-16 22:28 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-16 15:33 -0800
Re: Objective C supercat@casperkitty.com - 2015-11-16 15:56 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-17 01:43 +0000
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-17 01:21 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-16 18:11 -0800
Re: Objective C supercat@casperkitty.com - 2015-11-16 20:12 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-19 00:59 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-18 22:46 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-19 14:25 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-19 07:58 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-19 22:13 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-19 15:29 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 08:44 -0800
Re: Objective C glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-17 01:26 +0000
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-16 21:48 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-16 20:27 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-17 13:58 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-17 12:28 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-18 13:00 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-18 12:31 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-18 16:43 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-18 15:57 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-19 19:09 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-19 19:05 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-20 15:00 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-20 15:30 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-22 17:11 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-22 15:53 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-23 13:51 -0600
Re: Objective C raltbos@xs4all.nl (Richard Bos) - 2015-11-24 12:00 +0000
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-17 10:26 +0100
Re: Objective C supercat@casperkitty.com - 2015-11-17 06:20 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-17 16:41 +0100
Re: Objective C supercat@casperkitty.com - 2015-11-17 12:08 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-17 16:27 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-17 14:55 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-18 13:59 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-18 13:06 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-24 14:24 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-24 15:11 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-26 17:02 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-27 07:26 -0800
Re: Objective C supercat@casperkitty.com - 2015-11-18 21:56 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-22 02:17 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-22 07:16 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-26 17:11 -0600
Re: Objective C Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-22 19:09 +0000
Re: Objective C Robert Wessel <robertwessel2@yahoo.com> - 2015-11-17 23:28 -0600
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-18 15:33 +0100
Re: Objective C supercat@casperkitty.com - 2015-11-18 23:06 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-19 09:12 +0100
Re: Objective C supercat@casperkitty.com - 2015-11-19 09:25 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-19 21:06 +0100
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-20 13:49 -0800
Re: Objective C Robert Wessel <robertwessel2@yahoo.com> - 2015-11-21 05:01 -0600
Re: Objective C Robert Wessel <robertwessel2@yahoo.com> - 2015-11-21 05:09 -0600
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-21 03:31 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-21 17:43 -0600
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-21 16:00 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-22 01:12 -0600
Re: Objective C raltbos@xs4all.nl (Richard Bos) - 2015-11-27 16:42 +0000
Re: Objective C James Kuyper <jameskuyper@verizon.net> - 2015-11-27 12:38 -0500
Re: Objective C supercat@casperkitty.com - 2015-11-27 11:09 -0800
Re: Objective C James Kuyper <jameskuyper@verizon.net> - 2015-11-21 19:06 -0500
Re: Objective C supercat@casperkitty.com - 2015-11-21 17:00 -0800
Re: Objective C glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-22 14:44 +0000
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-22 01:55 -0600
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-22 00:03 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-22 10:18 +0000
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-23 03:21 -0800
Re: Objective C James Kuyper <jameskuyper@verizon.net> - 2015-11-22 10:53 -0500
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-22 20:28 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-22 18:52 -0800
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-23 11:58 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-23 15:24 -0800
Re: Objective C James Kuyper <jameskuyper@verizon.net> - 2015-11-23 09:46 -0500
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-23 08:13 -0800
Re: Objective C James Kuyper <jameskuyper@verizon.net> - 2015-11-23 12:04 -0500
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-23 11:52 -0600
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-23 16:05 -0800
Re: Objective C supercat@casperkitty.com - 2015-11-24 09:09 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-12-08 08:48 -0800
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-12-08 10:40 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-12-09 12:34 -0800
Re: Objective C supercat@casperkitty.com - 2015-12-08 10:50 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-12-09 12:42 -0800
Re: Objective C supercat@casperkitty.com - 2015-12-09 13:38 -0800
Re: Objective C raltbos@xs4all.nl (Richard Bos) - 2015-12-10 19:54 +0000
Re: Objective C David Thompson <dave.thompson2@verizon.net> - 2015-12-06 08:02 -0500
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-22 14:36 -0800
Re: Objective C Robert Wessel <robertwessel2@yahoo.com> - 2015-11-23 00:41 -0600
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-23 07:39 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-22 14:23 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-17 10:24 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-18 15:40 +0100
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-20 16:02 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-21 15:53 +0100
Re: Objective C supercat@casperkitty.com - 2015-11-21 08:58 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-22 22:14 +0100
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-23 03:39 -0800
Re: Objective C raltbos@xs4all.nl (Richard Bos) - 2015-11-23 13:24 +0000
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-26 09:39 -0800
Re: Objective C Robert Wessel <robertwessel2@yahoo.com> - 2015-11-26 13:16 -0600
Re: Objective C supercat@casperkitty.com - 2015-11-26 12:25 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 14:34 -0800
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-26 12:39 -0800
Re: Objective C raltbos@xs4all.nl (Richard Bos) - 2015-11-27 16:43 +0000
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-27 09:29 -0800
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 14:18 -0800
Re: Objective C glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-23 22:35 +0000
Re: Objective C James Kuyper <jameskuyper@verizon.net> - 2015-11-23 17:40 -0500
Re: Objective C glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-24 05:35 +0000
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-25 12:15 -0800
Re: Objective C glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-25 22:49 +0000
Re: Objective C raltbos@xs4all.nl (Richard Bos) - 2015-11-27 16:44 +0000
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 14:03 -0800
Re: Objective C Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-29 09:29 +0000
Re: Objective C Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-22 19:01 +0000
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-23 07:31 -0800
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-23 07:43 -0800
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-23 08:17 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-23 17:34 +0100
Re: Objective C Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-23 22:02 +0000
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-24 10:12 +0100
Re: Objective C Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 08:39 -0800
Re: Objective C Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-14 18:24 +0000
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-14 12:23 -0800
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-14 12:36 -0800
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-14 13:13 -0800
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-14 14:04 -0800
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-14 14:15 -0800
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-14 14:29 -0800
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-14 15:39 -0800
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-14 16:37 -0800
Re: Objective C Ian Collins <ian-news@hotmail.com> - 2015-11-15 13:46 +1300
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-15 02:06 +0000
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-15 03:25 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-15 12:56 +0000
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-15 07:53 -0600
Re: Objective C Stephen Sprunk <stephen@sprunk.org> - 2015-11-15 07:19 -0600
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-15 13:29 +0000
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-15 10:56 -0800
Re: Objective C supercat@casperkitty.com - 2015-11-15 14:35 -0800
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-15 16:52 -0800
Re: Objective C supercat@casperkitty.com - 2015-11-15 19:49 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-16 11:02 +0000
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-16 10:36 -0800
Re: Objective C David Thompson <dave.thompson2@verizon.net> - 2015-12-06 08:03 -0500
Re: Objective C Melzzzzz <mel@zzzzz.com> - 2015-11-16 02:01 +0100
Re: Objective C supercat@casperkitty.com - 2015-11-15 19:34 -0800
Re: Objective C Chad <cdalten@gmail.com> - 2015-11-15 19:54 -0800
Re: Objective C raltbos@xs4all.nl (Richard Bos) - 2015-11-17 22:36 +0000
Re: Objective C supercat@casperkitty.com - 2015-11-17 15:27 -0800
Re: Objective C Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-17 21:15 -0800
Re: Objective C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-14 22:08 +0000
Re: Objective C fir <profesor.fir@gmail.com> - 2015-11-27 14:36 -0800
Re: Objective C David Brown <david.brown@hesbynett.no> - 2015-11-10 19:03 +0100
Re: Objective C Keith Thompson <kst-u@mib.org> - 2015-11-10 10:50 -0800
Page 2 of 10 — ← Prev page 1 [2] 3 4 … 10 Next page →
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-15 19:10 -0800 |
| Message-ID | <d692da84-f162-4273-9cbd-a9a543c35869@googlegroups.com> |
| In reply to | #76137 |
On Sunday, November 15, 2015 at 4:50:38 PM UTC-6, David Brown wrote: > It's really strange how I manage to make a living doing many kinds of > embedded programming, using C99 and without relying on any assumed > effects of undefined behaviour, and using a variety of different > compilers (including the epitome of evil, gcc) - despite such > programming being totally impossible. Do you use it with or without -fno-strict-alias? If you use that option, you're not writing in Standard C, but rather in a vastly superior language. If not, I'd be very curious how you handle cases where blocks of memory are needed for different purposes at different times in different compilation units that may need to store objects of various internal-use-only types in them. If a change is made to an internal- use-only type used in one compilation unit to store temporary data into a shared scratchpad area, should that require recompilation of everything that uses the scratchpad? The only way I know of to handle such sharing would be to have a giant union of all applicable types, and I know of no way to use that without requiring such broad recompilations.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-11-16 09:11 +0100 |
| Message-ID | <n2c2ut$o6n$1@dont-email.me> |
| In reply to | #76155 |
On 16/11/15 04:10, supercat@casperkitty.com wrote: > On Sunday, November 15, 2015 at 4:50:38 PM UTC-6, David Brown wrote: >> It's really strange how I manage to make a living doing many kinds of >> embedded programming, using C99 and without relying on any assumed >> effects of undefined behaviour, and using a variety of different >> compilers (including the epitome of evil, gcc) - despite such >> programming being totally impossible. > > Do you use it with or without -fno-strict-alias? > Of course I compile with -fstrict-alias (via -O flags). I write in C, and I like my compiler to generate efficient object code so that I can write my source code in a clear and maintainable manner - I typically use most optimisation flags that do not result in excessive code size growth, and I have no need of flags that change the way C works. Code that /requires/ -fno-strict-alias is broken code. (And yes, for all that I like Linux and respect the kernel developers, Linus Torvalds is /wrong/ in some of his views on C and compilers.) > If you use that option, you're not writing in Standard C, but rather in a > vastly superior language. If not, I'd be very curious how you handle > cases where blocks of memory are needed for different purposes at different > times in different compilation units that may need to store objects of > various internal-use-only types in them. If a change is made to an internal- > use-only type used in one compilation unit to store temporary data into a > shared scratchpad area, should that require recompilation of everything that > uses the scratchpad? The only way I know of to handle such sharing would > be to have a giant union of all applicable types, and I know of no way to > use that without requiring such broad recompilations. > It sounds to me like you have trouble with basic code design. It is extremely rare that I need to re-interpret the same data as different types - and in those rare cases, there are three perfectly good and safe ways to handle it. You can use unions (and "giant unions" shows that your architecture is broken). You can use char pointers. And you can use memcpy (which the compiler should reduce to optimal code rather than a library call).
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-16 11:57 -0800 |
| Message-ID | <fff2ac89-757c-4d72-8307-9f48cd8327a6@googlegroups.com> |
| In reply to | #76167 |
On Monday, November 16, 2015 at 2:11:28 AM UTC-6, David Brown wrote:
> Of course I compile with -fstrict-alias (via -O flags). I write in C,
> and I like my compiler to generate efficient object code so that I can
> write my source code in a clear and maintainable manner - I typically
> use most optimisation flags that do not result in excessive code size
> growth, and I have no need of flags that change the way C works.
Can you explain to me how to handle either of the following situations?
FIRST SITUATION:
Two libraries written by different people will need to manipulate a
common buffer holding 16-bit integers, and for purposes of speed both
libraries will need to be able to process aligned pairs of integers
as pairs.
Is there any way to do that in compliance with even the most capricious
interpretation of aliasing rules without requiring both programmers to
agree in advance on the layout and name of a union containing two 16-bit
and one 32-bit values?
SECOND SITUATION:
To avoid memory fragmentation caused by use of malloc/free of different
size blocks, one wants to have code create pools of memory blocks and
allow functions distributed arbitrarily among compilation units to
request them, use them for storing data of types local to the compilation
units, and then release them so they may be re-used by other compilation
units without wasting time wiping the memory between uses [note that C
was clearly designed with the idea that if code didn't care about what
was in a newly-allocated block the allocation system shouldn't have to
wipe it; otherwise there would have been no need to include malloc() as
well as calloc].
What must code do between the time one function is done with a block of
memory before another function uses it? By my understanding, gcc is
assuming that given:
/* Compilation unit 1 --Assume necessarily includes, prototypes, etc.*/
static void *next_slot;
void *alloc(void)
{
void *temp = next_slot;
next_slot = 0;
return temp;
}
void release(void *dat)
{
next_slot = dat;
}
int main(void)
{
next_slot = malloc(sizeof (s1));
use_s1();
us2_s2();
}
/* Compilation unit 2 --Assume necessarily includes, prototypes, etc.*/
typedef struct {int x, int y;} s1; // For internal use only
void use_s1(void)
{
struct s1 *p1 = alloc();
p1->x = 1234;
printf("p1=%d\n",p1->x);
release(p1);
}
/* Compilation unit 3 --Assume necessarily includes, prototypes, etc.*/
typedef struct {int x, int y;} s2; // For internal use only
void use_s2(void)
{
struct s2 *p2 = alloc();
p2->x = 1234;
printf("p1=%d\n",p1->x);
release(p2);
}
there would be no required ordering between the writes of p1 and p2,
nor between the read of p1 and the write of p2. Am I not understanding
that correctly? Can the code be written in such a way that the Standard
would guarantee correct memory ordering without requiring that the two
compilation units expose their internal-use-only types s1 and s2?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-16 20:38 +0000 |
| Message-ID | <876111r86a.fsf@bsb.me.uk> |
| In reply to | #76199 |
supercat@casperkitty.com writes: > On Monday, November 16, 2015 at 2:11:28 AM UTC-6, David Brown wrote: >> Of course I compile with -fstrict-alias (via -O flags). I write in C, >> and I like my compiler to generate efficient object code so that I can >> write my source code in a clear and maintainable manner - I typically >> use most optimisation flags that do not result in excessive code size >> growth, and I have no need of flags that change the way C works. > > Can you explain to me how to handle either of the following situations? > > FIRST SITUATION: > > Two libraries written by different people will need to manipulate a > common buffer holding 16-bit integers, and for purposes of speed both > libraries will need to be able to process aligned pairs of integers > as pairs. > > Is there any way to do that in compliance with even the most capricious > interpretation of aliasing rules without requiring both programmers to > agree in advance on the layout and name of a union containing two 16-bit > and one 32-bit values? The description is incomplete in that we don't know the type of the buffer. You need to know the type to start with (presumably a 16-bit type) but provided you access the array through a lvalue expression that is a union containing a member of that type, I don't see how you are breaking any of the rules. > SECOND SITUATION: > > To avoid memory fragmentation caused by use of malloc/free of different > size blocks, one wants to have code create pools of memory blocks and > allow functions distributed arbitrarily among compilation units to > request them, use them for storing data of types local to the compilation > units, and then release them so they may be re-used by other compilation > units without wasting time wiping the memory between uses [note that C > was clearly designed with the idea that if code didn't care about what > was in a newly-allocated block the allocation system shouldn't have to > wipe it; otherwise there would have been no need to include malloc() as > well as calloc]. In this case I don't see the problem. For allocated objects, the effective type becomes the type used to write to the object. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-16 13:20 -0800 |
| Message-ID | <4e6ba271-859c-4d89-8603-2ea9fff9a1fc@googlegroups.com> |
| In reply to | #76202 |
On Monday, November 16, 2015 at 2:39:07 PM UTC-6, Ben Bacarisse wrote: > supercat writes: > > FIRST SITUATION: > > > > Two libraries written by different people will need to manipulate a > > common buffer holding 16-bit integers, and for purposes of speed both > > libraries will need to be able to process aligned pairs of integers > > as pairs. > > > > Is there any way to do that in compliance with even the most capricious > > interpretation of aliasing rules without requiring both programmers to > > agree in advance on the layout and name of a union containing two 16-bit > > and one 32-bit values? > > The description is incomplete in that we don't know the type of the > buffer. You need to know the type to start with (presumably a 16-bit > type) but provided you access the array through a lvalue expression that > is a union containing a member of that type, I don't see how you are > breaking any of the rules. From the standpoint of code outside the libraries, the buffer would only need to be used as a type uint16_t; the authors of the libraries would, however, want to be able to access aligned pairs of values simultaneously. If only one outside library needed to perform such access, I believe it could access the memory as a union type containing a uint32_t and a uint16_t while remaining compatible with the main code which access the data as a uint16_t. Unfortunately, if one of the libraries uses such a union for its access, the other library would by my understanding be limited to accessing the data as uint16_t or as the exact same union used by the first library. Is there any way that e.g. a library method that was supposed to find the first item in the array that wasn't equal to 12345 could take advantage of a 32-bit processor without having to expose such an implementation detail to the outside world? > > SECOND SITUATION: > > > > To avoid memory fragmentation caused by use of malloc/free of different > > size blocks, one wants to have code create pools of memory blocks and > > allow functions distributed arbitrarily among compilation units to > > request them, use them for storing data of types local to the compilation > > units, and then release them so they may be re-used by other compilation > > units without wasting time wiping the memory between uses [note that C > > was clearly designed with the idea that if code didn't care about what > > was in a newly-allocated block the allocation system shouldn't have to > > wipe it; otherwise there would have been no need to include malloc() as > > well as calloc]. > > In this case I don't see the problem. For allocated objects, the > effective type becomes the type used to write to the object. The write to p1 sets the effective type of the malloc'ed memory to s1. After the release() and alloc(), the effective type of that storage is still s1. What would authorize code to use a pointer of type s2 to write to the storage at that point? Post https://groups.google.com/forum/#!topic/comp.std.c/R8UpgWM7Nsk says that it's necessary to use malloc/free, but many embedded coding standards forbid their use after system startup because of the possibility of memory fragmentation. Is there any way to write valid C99 code which shares memory among libraries which use different internal data types, even if there's no need to share the contents? For that matter, if an embedded standard forbids use of malloc/free altogether, is it possible to write a memory allocator which returns blocks from a statically-allocated pool without the allocator having to know about every single structure code might try to store there?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-16 22:28 +0000 |
| Message-ID | <87k2phpoim.fsf@bsb.me.uk> |
| In reply to | #76203 |
supercat@casperkitty.com writes:
> On Monday, November 16, 2015 at 2:39:07 PM UTC-6, Ben Bacarisse wrote:
>> supercat writes:
>> > FIRST SITUATION:
>> >
>> > Two libraries written by different people will need to manipulate a
>> > common buffer holding 16-bit integers, and for purposes of speed both
>> > libraries will need to be able to process aligned pairs of integers
>> > as pairs.
>> >
>> > Is there any way to do that in compliance with even the most capricious
>> > interpretation of aliasing rules without requiring both programmers to
>> > agree in advance on the layout and name of a union containing two 16-bit
>> > and one 32-bit values?
>>
>> The description is incomplete in that we don't know the type of the
>> buffer. You need to know the type to start with (presumably a 16-bit
>> type) but provided you access the array through a lvalue expression that
>> is a union containing a member of that type, I don't see how you are
>> breaking any of the rules.
>
> From the standpoint of code outside the libraries, the buffer would only
> need to be used as a type uint16_t; the authors of the libraries would,
> however, want to be able to access aligned pairs of values simultaneously.
> If only one outside library needed to perform such access, I believe it
> could access the memory as a union type containing a uint32_t and a uint16_t
> while remaining compatible with the main code which access the data as a
> uint16_t. Unfortunately, if one of the libraries uses such a union for
> its access, the other library would by my understanding be limited to
> accessing the data as uint16_t or as the exact same union used by the
> first library.
I don't see the problem, but "used" is rather vague. To access the data
you need to know its effective type. Are you saying that one bit of
code has to work "bind" -- entirely unaware of the effective type of the
data? If so, I think your example is rather contrived.
> Is there any way that e.g. a library method that was supposed to find the
> first item in the array that wasn't equal to 12345 could take advantage of
> a 32-bit processor without having to expose such an implementation detail
> to the outside world?
Yes, I think so. Why can't it? What rule in the language standard
prevents it? (I'm assuming this is not about alignment...)
Here's an example. Take this function:
int f(int *ip, float *fp)
{
*ip = 42;
*fp = 42;
return *ip;
}
when called like this f(&i, (void *)&i) can return 42 because
the compiler can assume that ip and fp don't alias. However, write as
int f(int *ip, float *fp)
{
*ip = 42;
union { int i; float f; } *up = (void *)fp;
up->f = 4.2;
return *ip;
}
and I don't think it can anymore. This is how I (and I think the gcc
authors) interpret the rules. Is this at odds with your reading?
>> > SECOND SITUATION:
>> >
>> > To avoid memory fragmentation caused by use of malloc/free of different
>> > size blocks, one wants to have code create pools of memory blocks and
>> > allow functions distributed arbitrarily among compilation units to
>> > request them, use them for storing data of types local to the compilation
>> > units, and then release them so they may be re-used by other compilation
>> > units without wasting time wiping the memory between uses [note that C
>> > was clearly designed with the idea that if code didn't care about what
>> > was in a newly-allocated block the allocation system shouldn't have to
>> > wipe it; otherwise there would have been no need to include malloc() as
>> > well as calloc].
>>
>> In this case I don't see the problem. For allocated objects, the
>> effective type becomes the type used to write to the object.
>
> The write to p1 sets the effective type of the malloc'ed memory to s1.
> After the release() and alloc(), the effective type of that storage is
> still s1. What would authorize code to use a pointer of type s2 to
> write to the storage at that point?
The C standard. Can you cite the rule that says it can't? I feel I
must be missing something here because I assume it's the effective type
rules that you see as the problem, but they seem to allow it, so what is
the wording that causes the problem?
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-16 15:33 -0800 |
| Message-ID | <e43ebc47-dcd8-4424-94e5-837d3d40753d@googlegroups.com> |
| In reply to | #76208 |
On Monday, November 16, 2015 at 4:29:03 PM UTC-6, Ben Bacarisse wrote:
> supercat writes:
> I don't see the problem, but "used" is rather vague. To access the data
> you need to know its effective type. Are you saying that one bit of
> code has to work "bind" -- entirely unaware of the effective type of the
> data? If so, I think your example is rather contrived.
Targetting a 32-bit machine with linear address space, how would you write a
function to fill a uint16_t[] with the value 12345 if speed was important?
My inclination would be to write a function which checks whether the
received pointer is an odd multiple of 2, and if so store one value and
decrement the count. Then cast the pointer to some type to which one can
write 32 bits, store count/2 32-bit values, and then if the count was odd,
store one uint16_t at the end. On many platforms, that would be about
twice as fast as using uint16_t for everything, and on some it may be a lot
faster than that.
Some compilers might find the optimization if code was written using
uint16_t* for everything, but a lot wouldn't. If a compiler doesn't find
that optimization and performance is important, how should the code be
written?
>
> > Is there any way that e.g. a library method that was supposed to find the
> > first item in the array that wasn't equal to 12345 could take advantage of
> > a 32-bit processor without having to expose such an implementation detail
> > to the outside world?
>
> Yes, I think so. Why can't it? What rule in the language standard
> prevents it? (I'm assuming this is not about alignment...)
What 32-bit type could it use to read the data which would not risk falling afoul of the effective-type rules if it doesn't know what type was actually
used to write the data?
> However, write as
>
> int f(int *ip, float *fp)
> {
> *ip = 42;
> union { int i; float f; } *up = (void *)fp;
> up->f = 4.2;
> return *ip;
> }
>
> and I don't think it can anymore. This is how I (and I think the gcc
> authors) interpret the rules. Is this at odds with your reading?
Change the code a little:
void write_as_float(int *ip, float value)
{
union { int i; float f;} *up = (void*)ip;
up->f = value;
}
float read_as_float(int *ip)
{
union { float f; int i;} *up = (void*)ip;
return up->f;
}
int main(void)
{
void *p = malloc(100);
write_as_float(p, 123.456); // Defined
printf("%f", read_as_float(p)); // Kaboom
}
The write_as_float function would set the effective type of *up to that of
an anonymous union. The read_as_float function would attempt to access the
data as a different anonymous union. Since neither union type is a subset
of the other, I see nothing in the Standard that would make the access as
that second union type legitimate. Once the first method used a union to
set the effective type to that of the first anonymous union, the only valid
ways to work with the data after that would be as a character type, as that
first anonymous union, or as one of the types in that first union. Does
that not fit your reading?
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-16 15:56 -0800 |
| Message-ID | <4a5196c6-f52e-4901-9ab7-db7cd8f22286@googlegroups.com> |
| In reply to | #76212 |
On Monday, November 16, 2015 at 5:33:50 PM UTC-6, supe...@casperkitty.com wrote: > > However, write as... > > and I don't think it can anymore. This is how I (and I think the gcc > > authors) interpret the rules. Is this at odds with your reading? The rationale for the aliasing rule suggests that it was written to facilitate local optimizations, and I have no particular problem with that concept although I think the rule is not well designed even for those purposes; having standard macros which either map to directives that behave as aliasing barriers or do nothing on compilers that don't use aliasing rules, would have simultaneously eliminated the need for the "character" exception to the aliasing rules (thus allowing better optimizations) and allowed code which needs to use aliased values to less clunky than if it has to convert to unions whose sole purpose is to override the aliasing rules. Unfortunately, the authors of the aliasing rules neglected to provide any limits to their scope, or any means of limiting their scope. Code within a method can know what types might have been used to write an aliased pointer within that same method, and include all such types in a suitable union or, if types have different alignment requirements, nested group of unions. The optimization benefits of expanding the enforcement zone beyond a function to an entire compilation unit are apt to be far less than they were just within the function, but the difficulty of compliance can be massively increased. Expand enforcement to reach between compilation units and the difficulty of compliance increases massively, but on most implementations the additional optimization benefit would be zero. Do you disagree with that assessment?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-17 01:43 +0000 |
| Message-ID | <871tbppfi2.fsf@bsb.me.uk> |
| In reply to | #76213 |
supercat@casperkitty.com writes: > On Monday, November 16, 2015 at 5:33:50 PM UTC-6, supe...@casperkitty.com wrote: >> > However, write as... >> > and I don't think it can anymore. This is how I (and I think the gcc >> > authors) interpret the rules. Is this at odds with your reading? > > The rationale for the aliasing rule suggests that it was written to facilitate > local optimizations, and I have no particular problem with that concept > although I think the rule is not well designed even for those purposes; > having standard macros which either map to directives that behave as aliasing > barriers or do nothing on compilers that don't use aliasing rules, would have > simultaneously eliminated the need for the "character" exception to the > aliasing rules (thus allowing better optimizations) and allowed code which > needs to use aliased values to less clunky than if it has to convert to > unions whose sole purpose is to override the aliasing rules. > > Unfortunately, the authors of the aliasing rules neglected to provide any > limits to their scope, or any means of limiting their scope. Code within a > method can know what types might have been used to write an aliased pointer > within that same method, and include all such types in a suitable union or, > if types have different alignment requirements, nested group of unions. > The optimization benefits of expanding the enforcement zone beyond a function > to an entire compilation unit are apt to be far less than they were just > within the function, but the difficulty of compliance can be massively > increased. Expand enforcement to reach between compilation units and the > difficulty of compliance increases massively, but on most implementations > the additional optimization benefit would be zero. > > Do you disagree with that assessment? I think I agree, but, oddly, that leaves me unworried. I think you need relatively contrived cases to get a problem, and implementations are permitted (and presumably will) help out by defining the behaviour in cases where it matters for performance. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-17 01:21 +0000 |
| Message-ID | <877flhpgjh.fsf@bsb.me.uk> |
| In reply to | #76212 |
supercat@casperkitty.com writes:
> On Monday, November 16, 2015 at 4:29:03 PM UTC-6, Ben Bacarisse wrote:
>> supercat writes:
>> I don't see the problem, but "used" is rather vague. To access the data
>> you need to know its effective type. Are you saying that one bit of
>> code has to work "bind" -- entirely unaware of the effective type of the
>> data? If so, I think your example is rather contrived.
>
> Targetting a 32-bit machine with linear address space, how would you write a
> function to fill a uint16_t[] with the value 12345 if speed was
> important?
I'd try:
void fill(int16_t *data, size_t n, int16_t val)
{
if (n) {
*data = val;
size_t copy_sz = 1, remaining = n - 1;
while (remaining >= copy_sz) {
memcpy(data + copy_sz, data, copy_sz * sizeof *data);
remaining -= copy_sz;
copy_sz *= 2;
}
memcpy(data + n - remaining, data, remaining * sizeof *data);
}
}
in the hope that memcpy is fast.
> My inclination would be to write a function which checks whether the
> received pointer is an odd multiple of 2, and if so store one value and
> decrement the count. Then cast the pointer to some type to which one can
> write 32 bits, store count/2 32-bit values, and then if the count was odd,
> store one uint16_t at the end. On many platforms, that would be about
> twice as fast as using uint16_t for everything, and on some it may be a lot
> faster than that.
>
> Some compilers might find the optimization if code was written using
> uint16_t* for everything, but a lot wouldn't. If a compiler doesn't find
> that optimization and performance is important, how should the code be
> written?
There's no aliasing issue here. What optimisation do you think a
"hyper-modern" compiler will do when you access the data in the obvious
way? Is your concern just the "shall" in the standard, or have you
found a case where this actually matters in the absence of all aliasing?
Despite the "shall" most people take the footnote to be significant
("The intent of this list is to specify those circumstances in which an
object may or may not be aliased.").
I can't tell if your concern is with the words (I'm sure the text could
be improved in this area) or with the type-based aliasing optimisation
that modern compiler do. You paint it as a practical problem (what
compilers do to your previously well-understood code) but do any of them
play up in this case?
<huge snip>
Can you confirm that agree with me about your other example at least?
Can I assume that when you cut an answer altogether it's because you
have no objection to it?
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-16 18:11 -0800 |
| Message-ID | <50d2e6cb-6be8-475b-87c8-0d6fff9e0388@googlegroups.com> |
| In reply to | #76214 |
On Monday, November 16, 2015 at 7:21:23 PM UTC-6, Ben Bacarisse wrote:
> I'd try:
>
> void fill(int16_t *data, size_t n, int16_t val)
> {
> if (n) {
> *data = val;
> size_t copy_sz = 1, remaining = n - 1;
> while (remaining >= copy_sz) {
> memcpy(data + copy_sz, data, copy_sz * sizeof *data);
> remaining -= copy_sz;
> copy_sz *= 2;
> }
> memcpy(data + n - remaining, data, remaining * sizeof *data);
> }
> }
>
> in the hope that memcpy is fast.
Clever, though the fact that many of the items in the array have to be read
as well as written may negate any advantage that memcpy could have versus
a loop that simply stores values; that would probably depend upon the
implementation. Any idea how one could handle other operations, like
adding together groups of 16-bit values whose sum is known to be less than
65536?
> I can't tell if your concern is with the words (I'm sure the text could
> be improved in this area) or with the type-based aliasing optimisation
> that modern compiler do. You paint it as a practical problem (what
> compilers do to your previously well-understood code) but do any of them
> play up in this case?
Historically, for many forms of behavior where the Standard imposed no
requirements but where 99% of implementations would do the same thing,
compiler writers would generally try to abide by the Principle of Least
Astonishment. Some notable compiler writers, however, seem to have
overtly abandoned that principle, and taken the attitude that if the
Standard didn't guarantee that something would work, whether or not
there was ever any plausible reason why a compiler for a particular
platform would break it, they should feel no obligation to make code
which had previously yielded executables which were guaranteed by the
machine architecture to work in a fashion consistent with requirements,
continue to do so.
As the authors of gcc are eager to point out, the fact that today's
version of gcc doesn't break someone's code doesn't entitle that person
to believe that tomorrow's version won't. Thus, what matters is not
whether today's gcc optimizations would break the code, but whether the
Standard is written in such a way that no compiler could legitimately
break it, no matter how thorough its analysis.
> Can you confirm that agree with me about your other example at least?
> Can I assume that when you cut an answer altogether it's because you
> have no objection to it?
I botched the example with regard to malloc, and was too busy to formulate
a better one, but would still like to know if there's any way that a system
can implement a memory-pool-based allocator without using malloc/free. Is
there any way code can statically-allocate a buffer of known alignment that
can be made available for use as any type via a malloc-like function? As
noted, many coding standards are very restrictive on the use of malloc/free,
and I believe some important ones like MISRA ban them altogether.
If the main() had declared a buffer as a union containing a uint32_t and
a char[SIZE], the effective type of that union would, from what I can tell,
be the union type, which would thus not be compatible with any type other
than that union, uint32_t, or character types. Is my understanding
correct?
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-16 20:12 -0800 |
| Message-ID | <7c4f687f-742c-4adb-8639-d8fc95a9b78a@googlegroups.com> |
| In reply to | #76214 |
On Monday, November 16, 2015 at 7:21:23 PM UTC-6, Ben Bacarisse wrote:
> Can you confirm that agree with me about your other example at least?
> Can I assume that when you cut an answer altogether it's because you
> have no objection to it?
Could you help explain to me the aliasing implications of something like this?
void test1(float *fp, int *ip)
{
*fp = 12.3;
printf("%f", *fp);
*ip = 12;
printf("%d", *ip);
}
int main(void)
{
union { float f; int i; } u;
void *p = &u;
test1(p, p);
return 0;
}
When test1 is called from main, what would be the effective type of *fp and
*ip? Is the read of *fp guaranteed to happen before the write to *ip?
What if the code were:
void test1(float *fp)
{
*fp = 12.3;
printf("%f", *fp);
}
void test2(int *ip)
{
*ip = 12;
printf("%d", *ip);
}
int main(void)
{
union { float f; int i; } u;
void *p = &u;
test1(p);
test2(p);
return 0;
}
From what Linus Torvalds et al. were saying, gcc would be prone to reorder
the operations in a function like the first one. I can certainly see how
that could be useful from an optimization standpoint if the variables do
not alias, but it would be nonsensical if they do. The second would seem
like it should forbid a similar reordering (putting test1's load after
test2's store) but I don't see anything in the Standard that would make it
different from the first example.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-19 00:59 +0000 |
| Message-ID | <87mvuavm69.fsf@bsb.me.uk> |
| In reply to | #76219 |
supercat@casperkitty.com writes:
> On Monday, November 16, 2015 at 7:21:23 PM UTC-6, Ben Bacarisse wrote:
>> Can you confirm that agree with me about your other example at least?
>> Can I assume that when you cut an answer altogether it's because you
>> have no objection to it?
>
> Could you help explain to me the aliasing implications of something
> like this?
I'll try... I'm not an expert on this part of the standard.
> void test1(float *fp, int *ip)
> {
> *fp = 12.3;
> printf("%f", *fp);
> *ip = 12;
> printf("%d", *ip);
> }
>
> int main(void)
> {
> union { float f; int i; } u;
> void *p = &u;
> test1(p, p);
> return 0;
> }
>
> When test1 is called from main, what would be the effective type of *fp and
> *ip?
They both are accesses to the same object whose declared type is the
union.
> Is the read of *fp guaranteed to happen before the write to *ip?
No, the behaviour is undefined (by the language) so all bets are off.
> What if the code were:
>
> void test1(float *fp)
> {
> *fp = 12.3;
> printf("%f", *fp);
> }
>
> void test2(int *ip)
> {
> *ip = 12;
> printf("%d", *ip);
> }
>
> int main(void)
> {
> union { float f; int i; } u;
> void *p = &u;
> test1(p);
> test2(p);
> return 0;
> }
No change. Do you have an alternative view?
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-18 22:46 -0800 |
| Message-ID | <4f1444ba-a9e9-42bc-9d43-bc29b1a076c2@googlegroups.com> |
| In reply to | #76475 |
On Wednesday, November 18, 2015 at 6:59:50 PM UTC-6, Ben Bacarisse wrote:
> > When test1 is called from main, what would be the effective type of *fp and
> > *ip?
>
> They both are accesses to the same object whose declared type is the
> union.
A pointer to a union type, suitably converted, points to each of its
members (N1256 6.7.2.1 13).
Would it be legal to say:
union { int i; float f; } flint;
scanf("%d", &flint.i);
if nothing ever accessed flint.f? I can't think of any sensible reason why
the authors of the Standard would have intended to prohibit that, but at
the same time I can't think of any reason why it would be any less prohibited
than the original code. Since (N1256 6.7.2.1 13) doesn't actually say that
pointers to the members can be dereferenced, a strict reading of the Standard
would say that it merely guarantees that pointers, suitably converted, will
compare equal--not that they're actually useful for anything.
> No change. Do you have an alternative view?
What I'm coming to accept is that the Standard was written in a fashion which simply makes it impossible to have code reuse memory efficiently in
many cases, and the only reason C ever achieved any dominance in most of the
fields where it has is that compiler writers assumed the authors of the
Standard intended to write rules which would not impair programmers' ability
to write speed- and time-efficient code but at worst require programmers to
use some extra syntactical clunkiness in certain places, and thus interpreted
the rules with that intention in mind.
While people writing programs where extra memory usage and otherwise-needless
calls to malloc/free are no big deal may be perfectly happy with strict
aliasing semantics, C-with-strict-aliasing-semantics is simply incapable of
yielding efficient code in many cases without wasting time, memory, or both.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-19 14:25 +0000 |
| Message-ID | <87r3jmt6ac.fsf@bsb.me.uk> |
| In reply to | #76487 |
supercat@casperkitty.com writes:
> On Wednesday, November 18, 2015 at 6:59:50 PM UTC-6, Ben Bacarisse wrote:
>> > When test1 is called from main, what would be the effective type of *fp and
>> > *ip?
>>
>> They both are accesses to the same object whose declared type is the
>> union.
>
> A pointer to a union type, suitably converted, points to each of its
> members (N1256 6.7.2.1 13).
Not sure I see the relevance...
> Would it be legal to say:
>
> union { int i; float f; } flint;
> scanf("%d", &flint.i);
>
> if nothing ever accessed flint.f?
Yes, it would. Why do you think it might not be?
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-19 07:58 -0800 |
| Message-ID | <63c43be8-de88-4f9c-b24c-9566243b0dc3@googlegroups.com> |
| In reply to | #76518 |
On Thursday, November 19, 2015 at 8:26:03 AM UTC-6, Ben Bacarisse wrote:
> supercat writes:
>
> > On Wednesday, November 18, 2015 at 6:59:50 PM UTC-6, Ben Bacarisse wrote:
> >> > When test1 is called from main, what would be the effective type of *fp and
> >> > *ip?
> >>
> >> They both are accesses to the same object whose declared type is the
> >> union.
> >
> > A pointer to a union type, suitably converted, points to each of its
> > members (N1256 6.7.2.1 13).
>
> Not sure I see the relevance...
> > Would it be legal to say:
> >
> > union { int i; float f; } flint;
> > scanf("%d", &flint.i);
> >
> > if nothing ever accessed flint.f?
>
> Yes, it would. Why do you think it might not be?
I was confused for the longest time by the belief that it was legal, but
recognizing that it isn't makes things a lot clearer.
Were it not for the provision in N1570 6.5.7 which mentions unions, it would
be illegal to access union members in any way whatsoever (which obviously
wouldn't be useful); the only thing which is authorized by that section is
accessing members of the union through an lvalue of the union type (as would
be done with "flint.i=123;"). The call to scanf does not cause flint to be
modified using an lvalue of type "flint"; it causes it to be modified with an
lvalue of type "int", and in the process illegitimately modifies flint.f.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-19 22:13 +0000 |
| Message-ID | <87bnaptz7w.fsf@bsb.me.uk> |
| In reply to | #76531 |
supercat@casperkitty.com writes:
> On Thursday, November 19, 2015 at 8:26:03 AM UTC-6, Ben Bacarisse wrote:
>> supercat writes:
>>
>> > On Wednesday, November 18, 2015 at 6:59:50 PM UTC-6, Ben Bacarisse wrote:
>> >> > When test1 is called from main, what would be the effective
>> >> > type of *fp and
>> >> > *ip?
>> >>
>> >> They both are accesses to the same object whose declared type is the
>> >> union.
>> >
>> > A pointer to a union type, suitably converted, points to each of its
>> > members (N1256 6.7.2.1 13).
>>
>> Not sure I see the relevance...
>
>> > Would it be legal to say:
>> >
>> > union { int i; float f; } flint;
>> > scanf("%d", &flint.i);
>> >
>> > if nothing ever accessed flint.f?
>>
>> Yes, it would. Why do you think it might not be?
>
> I was confused for the longest time by the belief that it was legal, but
> recognizing that it isn't makes things a lot clearer.
>
> Were it not for the provision in N1570 6.5.7 which mentions unions, it would
> be illegal to access union members in any way whatsoever (which obviously
> wouldn't be useful); the only thing which is authorized by that section is
> accessing members of the union through an lvalue of the union type (as would
> be done with "flint.i=123;"). The call to scanf does not cause flint to be
> modified using an lvalue of type "flint"; it causes it to be modified with an
> lvalue of type "int", and in the process illegitimately modifies
> flint.f.
Why would you read it like that? If that argument were valid, flint.i =
42; would be undefined because flint would be accessed through an lvalue
of type int rather than one with the union type. Clearly that is not
the intent. flint.i = 42; is access to an object of type int and it is
done though an lvalue with teh declared type of that object (int).
Now, you can argue that this should be clearer; you can say that more
needs to be said about union, objects and accesses, but there can't be
any doubt that a reading which prevents flint.i = 42 because is
illegitimately modifies flint.f can't be right.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-11-19 15:29 -0800 |
| Message-ID | <0f0c0135-dd21-43cd-bda8-7ab49e74deef@googlegroups.com> |
| In reply to | #76561 |
On Thursday, November 19, 2015 at 4:13:16 PM UTC-6, Ben Bacarisse wrote:
> supercat writes:
>
> > On Thursday, November 19, 2015 at 8:26:03 AM UTC-6, Ben Bacarisse wrote:
> >> supercat writes:
> >>
> >> > On Wednesday, November 18, 2015 at 6:59:50 PM UTC-6, Ben Bacarisse wrote:
> >> >> > When test1 is called from main, what would be the effective
> >> >> > type of *fp and
> >> >> > *ip?
> >> >>
> >> >> They both are accesses to the same object whose declared type is the
> >> >> union.
> >> >
> >> > A pointer to a union type, suitably converted, points to each of its
> >> > members (N1256 6.7.2.1 13).
> >>
> >> Not sure I see the relevance...
> >
> >> > Would it be legal to say:
> >> >
> >> > union { int i; float f; } flint;
> >> > scanf("%d", &flint.i);
> >> >
> >> > if nothing ever accessed flint.f?
> >>
> >> Yes, it would. Why do you think it might not be?
> >
> > I was confused for the longest time by the belief that it was legal, but
> > recognizing that it isn't makes things a lot clearer.
> >
> > Were it not for the provision in N1570 6.5.7 which mentions unions, it would
> > be illegal to access union members in any way whatsoever (which obviously
> > wouldn't be useful); the only thing which is authorized by that section is
> > accessing members of the union through an lvalue of the union type (as would
> > be done with "flint.i=123;"). The call to scanf does not cause flint to be
> > modified using an lvalue of type "flint"; it causes it to be modified with an
> > lvalue of type "int", and in the process illegitimately modifies
> > flint.f.
>
> Why would you read it like that? If that argument were valid, flint.i =
> 42; would be undefined because flint would be accessed through an lvalue
> of type int rather than one with the union type. Clearly that is not
> the intent. flint.i = 42; is access to an object of type int and it is
> done though an lvalue with teh declared type of that object (int).
I see an lvalue of type a union type in that assignment. If it were
dereference pointers to union members without converting them to character
pointers, that would suggest that having:
int foo(float *f, int *i) { *i = 3; *f = 12.3; return *i; }
in one compilation unit and
foo(&flint.f, &flint.i);
in another would cause foo to yield an Unspecified value rather than
yielding Undefined Behavior, but the intention of the rules is clearly
to allow the latter without requiring that a compiler prove that the
two objects can't possibly both be members of the same union type,
since in most aliasing situations a compiler would not be able to prove
that.
> Now, you can argue that this should be clearer; you can say that more
> needs to be said about union, objects and accesses, but there can't be
> any doubt that a reading which prevents flint.i = 42 because is
> illegitimately modifies flint.f can't be right.
The statement "flint.i" accesses memory through an lvalue of type "flint".
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-11-27 08:44 -0800 |
| Message-ID | <kfnmvtz1jer.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #76531 |
supercat@casperkitty.com writes:
> On Thursday, November 19, 2015 at 8:26:03 AM UTC-6, Ben Bacarisse wrote:
>> supercat writes:
>>
>>> On Wednesday, November 18, 2015 at 6:59:50 PM UTC-6, Ben Bacarisse wrote:
>>>>> When test1 is called from main, what would be the effective
>>>>> type of *fp and *ip?
>>>>
>>>> They both are accesses to the same object whose declared type
>>>> is the union.
>>>
>>> A pointer to a union type, suitably converted, points to each of
>>> its members (N1256 6.7.2.1 13).
>>
>> Not sure I see the relevance...
>>
>>> Would it be legal to say:
>>>
>>> union { int i; float f; } flint;
>>> scanf("%d", &flint.i);
>>>
>>> if nothing ever accessed flint.f?
>>
>> Yes, it would. Why do you think it might not be?
>
> I was confused for the longest time by the belief that it was
> legal, but recognizing that it isn't makes things a lot clearer.
>
> Were it not for the provision in N1570 6.5[p]7 which mentions
> unions, it would be illegal to access union members in any way
> whatsoever [...]
Nonsense.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-11-17 01:26 +0000 |
| Message-ID | <n2dvo0$f0h$1@speranza.aioe.org> |
| In reply to | #76212 |
supercat@casperkitty.com wrote: > On Monday, November 16, 2015 at 4:29:03 PM UTC-6, Ben Bacarisse wrote: >> supercat writes: >> I don't see the problem, but "used" is rather vague. To access the data >> you need to know its effective type. Are you saying that one bit of >> code has to work "bind" -- entirely unaware of the effective type of the >> data? If so, I think your example is rather contrived. > Targetting a 32-bit machine with linear address space, how would you write a > function to fill a uint16_t[] with the value 12345 if speed was important? > My inclination would be to write a function which checks whether the > received pointer is an odd multiple of 2, and if so store one value and > decrement the count. Then cast the pointer to some type to which one can > write 32 bits, store count/2 32-bit values, and then if the count was odd, > store one uint16_t at the end. On many platforms, that would be about > twice as fast as using uint16_t for everything, and on some it may be a lot > faster than that. It would be nice if memcpy() did optimizations like that. C is used for many things that used to be done in assembler, but that doesn't make it an assembler. It might have been nice to have two versions of memcpy(), one optimized for large copies, and one for small. Such optimizations usually make sense for large ones. One reason C does well is that, in most cases, one doesn't need to optimize cases like that. Higher level optizations should be done by the user, lower level ones by the compiler or library. -- glen
[toc] | [prev] | [next] | [standalone]
Page 2 of 10 — ← Prev page 1 [2] 3 4 … 10 Next page →
Back to top | Article view | comp.lang.c
csiph-web