Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #112012 > unrolled thread
| Started by | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| First post | 2017-06-12 06:57 -0700 |
| Last post | 2017-06-14 11:24 +0100 |
| Articles | 19 on this page of 39 — 13 participants |
Back to article view | Back to comp.lang.c
Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-12 06:57 -0700
Re: Unexpected error on x[0] != y[0] bartc <bc@freeuk.com> - 2017-06-12 15:11 +0100
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-12 07:18 -0700
Re: Unexpected error on x[0] != y[0] bartc <bc@freeuk.com> - 2017-06-12 15:29 +0100
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-12 07:41 -0700
Re: Unexpected error on x[0] != y[0] bartc <bc@freeuk.com> - 2017-06-12 18:32 +0100
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-12 10:56 -0700
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-13 08:14 -0700
Re: Unexpected error on x[0] != y[0] bartc <bc@freeuk.com> - 2017-06-13 17:52 +0100
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-13 10:00 -0700
Re: Unexpected error on x[0] != y[0] scott@slp53.sl.home (Scott Lurndal) - 2017-06-13 17:19 +0000
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-13 10:33 -0700
Re: Unexpected error on x[0] != y[0] scott@slp53.sl.home (Scott Lurndal) - 2017-06-13 17:56 +0000
Re: Unexpected error on x[0] != y[0] Gareth Owen <gwowen@gmail.com> - 2017-06-13 19:45 +0100
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-13 17:54 -0700
Re: Unexpected error on x[0] != y[0] joel.rees@gmail.com - 2017-06-13 20:57 -0700
Re: Unexpected error on x[0] != y[0] Gareth Owen <gwowen@gmail.com> - 2017-06-14 06:41 +0100
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-14 03:37 -0700
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-14 03:54 -0700
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-13 17:45 -0700
Re: Unexpected error on x[0] != y[0] David Brown <david.brown@hesbynett.no> - 2017-06-14 08:49 +0200
Re: Unexpected error on x[0] != y[0] bartc <bc@freeuk.com> - 2017-06-13 19:07 +0100
Re: Unexpected error on x[0] != y[0] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-13 19:23 +0100
Re: Unexpected error on x[0] != y[0] bartc <bc@freeuk.com> - 2017-06-13 22:30 +0100
Re: Unexpected error on x[0] != y[0] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-13 23:29 +0100
Re: Unexpected error on x[0] != y[0] supercat@casperkitty.com - 2017-06-13 11:51 -0700
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-13 17:53 -0700
Re: Unexpected error on x[0] != y[0] Reinhardt Behm <rbehm@hushmail.com> - 2017-06-14 13:34 +0800
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-14 03:24 -0700
Re: Unexpected error on x[0] != y[0] David Brown <david.brown@hesbynett.no> - 2017-06-14 09:10 +0200
Re: Unexpected error on x[0] != y[0] John Bode <jfbode1029@gmail.com> - 2017-06-12 07:26 -0700
Re: Unexpected error on x[0] != y[0] "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-12 10:54 -0400
Re: Unexpected error on x[0] != y[0] Keith Thompson <kst-u@mib.org> - 2017-06-12 09:23 -0700
Re: Unexpected error on x[0] != y[0] Gareth Owen <gwowen@gmail.com> - 2017-06-12 19:05 +0100
Re: Unexpected error on x[0] != y[0] Anton Shepelev <anton.txt@gmail.com> - 2017-06-12 17:29 +0300
Re: Unexpected error on x[0] != y[0] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-12 15:52 +0100
Re: Unexpected error on x[0] != y[0] "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2017-06-12 08:31 -0700
Re: Unexpected error on x[0] != y[0] joel.rees@gmail.com - 2017-06-13 22:09 -0700
Re: Unexpected error on x[0] != y[0] Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-14 11:24 +0100
Page 2 of 2 — ← Prev page 1 [2]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-14 08:49 +0200 |
| Message-ID | <ohqm27$lrq$1@dont-email.me> |
| In reply to | #112144 |
On 14/06/17 02:45, Rick C. Hodgin wrote:
> On Tuesday, June 13, 2017 at 1:56:57 PM UTC-4, Scott Lurndal wrote:
>> "Rick C. Hodgin" <rick.c.hodgin@gmail.com> writes:
>>> On Tuesday, June 13, 2017 at 1:19:16 PM UTC-4, Scott Lurndal wrote:
>>>> You mean like Python? Or R? or SQL?
>>> No. I mean more like what's allowed at the assembly level. Something
>>> similar would also be allowed in CAlive's use and access to data, but
>>> with more guidance and management than what assembly would give you, so
>>> as to help prevent errors, while still affording a developer that low-
>>> level power when needed.
>>
>> Who would possibly want such a thing, and for what purpose?
>
> Why would someone write code in C? There are languages far easier and
> less prone to error to write code in. C is fastest if it's done properly.
Certainly a lot of code written in C could be better written in other
languages, and a lot of people who /learn/ C could be more productive
learning other languages. But there are also many reasons why C can be
a good choice - speed is just one, and often not the main one.
> But even so, it's not as fast as assembly can be ... if it's also done
> properly.
No, C done properly is usually faster than assembly done properly. By
"done properly", I mean writing clear, flexible, maintainable, correct
and re-usable code. That is very hard to do in assembly, and does not
combine well with trying to get optimal speed. And at best with
assembly, you usually only end up with something that is optimal for a
particular processor - a particular member of a particular family. All
your effort and fine-tuning is wasted the next year when there is a new
chip with a different balance in instruction scheduling and pipelining.
Sometimes short sections of code can be best done in assembly, and
sometimes it gives access to specially fast instructions (like SIMD
vector processing) - but even then, compilers are getting better at
using them.
>
> By giving people tools to dip down into that lower-level, by seeing and
> recognizing data as data and not as fundamental C types, it then gives
> them a new ability to potentially access things in ways that wasn't
> previously possible within C-like forms alone.
Nah, it is all possible with C now. But you may need
implementation-specific C rather than portable standard C. That's fine,
of course, and one of the purposes of the way the language is designed -
it is made so that you can write code that is finely tuned to a
particular implementation (compiler, target or combination). So C has
somewhat abstract data types like "int" whose size is not universally
fixed, with different possibilities for how it is stored, and no two's
complement wrap on overflow. But when you decide on a particular
implementation - say, gcc on 32-bit x86 - you can get as low level as
you want. Now you can get to the 32 bits that make up your "int", and
can use compiler flags, pragmas, casts, etc., to get two's complement
wrapping overflow if you like.
>
> I'm also going to try to allow inline assembly instructions which are
> able to access data without having to use _asm {..} blocks.
>
> But, that's a low priority.
>
> Thank you,
> Rick C. Hodgin
>
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-13 19:07 +0100 |
| Message-ID | <qRV%A.139886$dE4.100852@fx36.am4> |
| In reply to | #112113 |
On 13/06/2017 18:00, Rick C. Hodgin wrote:
> On Tuesday, June 13, 2017 at 12:53:01 PM UTC-4, Bart wrote:
>> That doesn't sound a good move! Well, not unless this new language is
>> expected to be lower level than C.
>
> Full typing protocols can be enforced, and will be warned about
> regardless. But my goals are to provide people with a high-end
> data processing tool, one which allows people (as the developers
> in charge) to bypass types and access the data they seek as they
> are able if they're willing to do so in a way that operates
> outside of typing.
The casts will do that in C. But there are other ways. This would be a
useful feature for C I think:
union {
int a;
int b[10];
float x;
};
This is legal syntax now, but doesn't do anything. The intention is that
in this form, it declares variables a, b and x that all occupy the same
location (the start of a 40-byte block).
Then you can write x=1.0; and print out its bit pattern using a.
There is another similar feature but that is not as tidy; I used to use
it like this:
int64 c @ &b[4]
where the b is the 10-int array. Now, c is a 64-bit value occupying the
same location as b[4] and b[5].
So you can do sharing of memory, and read it in whichever way you like.
You have to use a different identifier for each type, but that is better.
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-13 19:23 +0100 |
| Message-ID | <87d1a7agqq.fsf@bsb.me.uk> |
| In reply to | #112120 |
bartc <bc@freeuk.com> writes:
<snip>
> ... This would be a useful feature for C I think:
>
> union {
> int a;
> int b[10];
> float x;
> };
>
> This is legal syntax now, but doesn't do anything.
I'm not sure what you mean by this. It does what you say the intention
if the code is below:
> The intention is
> that in this form, it declares variables a, b and x that all occupy
> the same location (the start of a 40-byte block).
>
> Then you can write x=1.0; and print out its bit pattern using a.
Yes, you can do that (provided the x rather than u.x was a typo).
unsigned int is is slightly more convenient, and you have to take with
the sizes but that's all.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-13 22:30 +0100 |
| Message-ID | <yPY%A.45572$y7.34196@fx15.am4> |
| In reply to | #112122 |
On 13/06/2017 19:23, Ben Bacarisse wrote:
> bartc <bc@freeuk.com> writes:
> <snip>
>> ... This would be a useful feature for C I think:
>>
>> union {
>> int a;
>> int b[10];
>> float x;
>> };
>>
>> This is legal syntax now, but doesn't do anything.
>
> I'm not sure what you mean by this.
It defines an anonymous union. Since it is anonymous, you can't use it
to define any variables, and it doesn't any variables itself. So there's
not point in it.
My intention was for it to be the equivalent of this:
int a;
int b[10];
float x;
but with a, b and x all starting at the same memory location. Using my
other idea, it could be written like this:
int b[10];
int a @ b;
float x @ b;
(When I implemented this elsewhere, I needed the biggest item to be
defined first.)
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-13 23:29 +0100 |
| Message-ID | <877f0fa5da.fsf@bsb.me.uk> |
| In reply to | #112135 |
bartc <bc@freeuk.com> writes:
> On 13/06/2017 19:23, Ben Bacarisse wrote:
>> bartc <bc@freeuk.com> writes:
>> <snip>
>>> ... This would be a useful feature for C I think:
>>>
>>> union {
>>> int a;
>>> int b[10];
>>> float x;
>>> };
>>>
>>> This is legal syntax now, but doesn't do anything.
>>
>> I'm not sure what you mean by this.
>
> It defines an anonymous union.
Technically, no[1], but that's enough for me to know what you intended --
you want the effect of an anonymous union outside of a struct, directly
in a collection of declarations.
> Since it is anonymous, you can't use it to define any variables, and
> it doesn't any variables itself. So there's not point in it.
>
> My intention was for it to be the equivalent of this:
>
> int a;
> int b[10];
> float x;
What's wrong with using a union? Are you proposing a new feature simply
to avoid writing u.x?
[1] The term, in C, applies only to struct or union members.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-06-13 11:51 -0700 |
| Message-ID | <2e301979-ea55-4eec-a3ac-df0d65617abc@googlegroups.com> |
| In reply to | #112120 |
On Tuesday, June 13, 2017 at 1:07:25 PM UTC-5, Bart wrote:
> The casts will do that in C. But there are other ways. This would be a
> useful feature for C I think:
>
> union {
> int a;
> int b[10];
> float x;
> };
There are at least three useful meanings such a declaration could have:
1. Demand that a compiler recognize aliasing amoung common-initial-sequence
members of all structure types listed therein without a programmer having
to meet gcc's impractical requirement of using lvalues of that type. This
could slightly impede some optimizations, but most code that would need
this feature would otherwise need to be written to block those phony
"optimizations" via other means.
2. Demand that a compiler recognize aliasing among values of all types listed
therein (though not necessarily transitively with members of other unions).
That could be a major optimization hit in cases where code didn't require
such aliasing, but if code does require such aliasing, correctness should
trump speed.
3. Export all the union memebers as identifiers in their own right in the
surrounding scope, assuming member x to be accessed as x, rather than as
someUnion.x.
Meaning #3 is most analogous to the way declarations work within a nested
struct or union, but it might be better to say that a declaration like:
struct { ... } auto x;
or
struct foo auto x;
will create an object of that structure type in the current scope and
*also* create shorthand identifiers for each member thereof. Such an
approach could be particularly useful when adapting existing code in
cases where it's necessary to be able to treat some variables as a unit
for purposes of things like fread/fwrite.
> This is legal syntax now, but doesn't do anything. The intention is that
> in this form, it declares variables a, b and x that all occupy the same
> location (the start of a 40-byte block).
I think it's should at least take care of meaning #1 (assuming the Standard
has any reason for saying "complete union type"), though the authors of
gcc and clang seem to think programmers should have to jump through hoops
to access useful semantics that had been available since C74.
[toc] | [prev] | [next] | [standalone]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2017-06-13 17:53 -0700 |
| Message-ID | <670bc770-e4d2-4a22-9217-2c888278a18e@googlegroups.com> |
| In reply to | #112120 |
On Tuesday, June 13, 2017 at 2:07:25 PM UTC-4, Bart wrote:
> On 13/06/2017 18:00, Rick C. Hodgin wrote:
> > On Tuesday, June 13, 2017 at 12:53:01 PM UTC-4, Bart wrote:
> >> That doesn't sound a good move! Well, not unless this new language is
> >> expected to be lower level than C.
I had a discussion with someone at my work yesterday. I was considering
calling it KAlive rather than CAlive. It's the hard sound of C, and is
also a little more primitive, akin to how children learn to spell "cat"
as "kat" before they realize C also makes that sound.
I don't know. I haven't decided yet. The goal of CAlive is to be 100%
compatible with C when those options are enabled, but to also allow the
developer to bypass C requirements and program at the data level, and
even down to the assembly level if need be, from the single source tool.
> > Full typing protocols can be enforced, and will be warned about
> > regardless. But my goals are to provide people with a high-end
> > data processing tool, one which allows people (as the developers
> > in charge) to bypass types and access the data they seek as they
> > are able if they're willing to do so in a way that operates
> > outside of typing.
>
> The casts will do that in C. But there are other ways. This would be a
> useful feature for C I think:
>
> union {
> int a;
> int b[10];
> float x;
> };
As I understand it, unions only allow valid extraction from the storage
of the type last written to it. I write an int into a, and I can only
legally extract an int out from a. Even b[0] would not technically be
legal.
My argument all along has been that such a constraint is ridiculous,
and that the purpose of the union should be exactly this type of non-
cast conversion.
> This is legal syntax now, but doesn't do anything. The intention is that
> in this form, it declares variables a, b and x that all occupy the same
> location (the start of a 40-byte block).
>
> Then you can write x=1.0; and print out its bit pattern using a.
>
> There is another similar feature but that is not as tidy; I used to use
> it like this:
>
> int64 c @ &b[4]
>
> where the b is the 10-int array. Now, c is a 64-bit value occupying the
> same location as b[4] and b[5].
>
> So you can do sharing of memory, and read it in whichever way you like.
> You have to use a different identifier for each type, but that is better.
In CAlive, I allow every variable to be referenced by its name prefixed
with an underscore, which is the unsigned int equivalent of whatever type
it is. It does not require a union, but allows everything to be used as
an unsigned integer of its bytes, used for passing things around, setting
things without casting, etc.
I am explicitly using it for pointers, and for function pointers, where
the my_func() function is referenced as _my_func to reference its address.
Thank you,
Rick C. Hodgin
[toc] | [prev] | [next] | [standalone]
| From | Reinhardt Behm <rbehm@hushmail.com> |
|---|---|
| Date | 2017-06-14 13:34 +0800 |
| Message-ID | <ohqhme$ama$1@dont-email.me> |
| In reply to | #112145 |
AT Wednesday 14 June 2017 08:53, Rick C. Hodgin wrote:
> On Tuesday, June 13, 2017 at 2:07:25 PM UTC-4, Bart wrote:
>> On 13/06/2017 18:00, Rick C. Hodgin wrote:
>> > On Tuesday, June 13, 2017 at 12:53:01 PM UTC-4, Bart wrote:
>> >> That doesn't sound a good move! Well, not unless this new language is
>> >> expected to be lower level than C.
>
> I had a discussion with someone at my work yesterday. I was considering
> calling it KAlive rather than CAlive. It's the hard sound of C, and is
> also a little more primitive, akin to how children learn to spell "cat"
> as "kat" before they realize C also makes that sound.
>
> I don't know. I haven't decided yet. The goal of CAlive is to be 100%
> compatible with C when those options are enabled, but to also allow the
> developer to bypass C requirements and program at the data level, and
> even down to the assembly level if need be, from the single source tool.
>
>> > Full typing protocols can be enforced, and will be warned about
>> > regardless. But my goals are to provide people with a high-end
>> > data processing tool, one which allows people (as the developers
>> > in charge) to bypass types and access the data they seek as they
>> > are able if they're willing to do so in a way that operates
>> > outside of typing.
>>
>> The casts will do that in C. But there are other ways. This would be a
>> useful feature for C I think:
>>
>> union {
>> int a;
>> int b[10];
>> float x;
>> };
>
> As I understand it, unions only allow valid extraction from the storage
> of the type last written to it. I write an int into a, and I can only
> legally extract an int out from a. Even b[0] would not technically be
> legal.
>
> My argument all along has been that such a constraint is ridiculous,
> and that the purpose of the union should be exactly this type of non-
> cast conversion.
>
>> This is legal syntax now, but doesn't do anything. The intention is that
>> in this form, it declares variables a, b and x that all occupy the same
>> location (the start of a 40-byte block).
>>
>> Then you can write x=1.0; and print out its bit pattern using a.
>>
>> There is another similar feature but that is not as tidy; I used to use
>> it like this:
>>
>> int64 c @ &b[4]
>>
>> where the b is the 10-int array. Now, c is a 64-bit value occupying the
>> same location as b[4] and b[5].
>>
>> So you can do sharing of memory, and read it in whichever way you like.
>> You have to use a different identifier for each type, but that is better.
>
> In CAlive, I allow every variable to be referenced by its name prefixed
> with an underscore, which is the unsigned int equivalent of whatever type
> it is. It does not require a union, but allows everything to be used as
> an unsigned integer of its bytes, used for passing things around, setting
> things without casting, etc.
>
> I am explicitly using it for pointers, and for function pointers, where
> the my_func() function is referenced as _my_func to reference its address.
You should have a look at PL/I. There you have the unspec() "function". It
gives defined access to the underlying bit-representation. It can even be
used on the left side of an assignment.
Using it gives clearly defined results without any dirty tricks like using
unions to masquerade these tricks.
> Thank you,
> Rick C. Hodgin
--
Reinhardt
[toc] | [prev] | [next] | [standalone]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2017-06-14 03:24 -0700 |
| Message-ID | <96e177cf-24a3-4625-a345-e5ef3cd7e073@googlegroups.com> |
| In reply to | #112163 |
Reinhardt Behm wrote: > You should have a look at PL/I... I'll look into it, Reinhardt. Thank you, Rick C. Hodgin
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-14 09:10 +0200 |
| Message-ID | <ohqnan$pc4$1@dont-email.me> |
| In reply to | #112145 |
On 14/06/17 02:53, Rick C. Hodgin wrote:
> On Tuesday, June 13, 2017 at 2:07:25 PM UTC-4, Bart wrote:
>> On 13/06/2017 18:00, Rick C. Hodgin wrote:
>> The casts will do that in C. But there are other ways. This would be a
>> useful feature for C I think:
>>
>> union {
>> int a;
>> int b[10];
>> float x;
>> };
>
> As I understand it, unions only allow valid extraction from the storage
> of the type last written to it. I write an int into a, and I can only
> legally extract an int out from a. Even b[0] would not technically be
> legal.
See C11 n1570 sections 6.5.2.3 and 6.2.6.1. This is called "type
punning", and is defined behaviour. (I believe it was not well
expressed in some earlier standard versions, but since compilers
supported it and code relied on it, it was clarified in the later
standards.)
There are still some gotchas. For example, if you write something to
"b", then write to "a", the parts of "b" beyond the overlap with "a"
take unspecified values. A compiler might use that if it made a
difference in execution speed - for example, if "a" were a 16-bit short,
and the processor has no 16-bit write instruction (such as early ARM
devices, or Alpha cpus), then the write could stomp over b[2] and b[3].
>
> My argument all along has been that such a constraint is ridiculous,
> and that the purpose of the union should be exactly this type of non-
> cast conversion.
Well, yes. The C committee thought so too.
>
>> This is legal syntax now, but doesn't do anything. The intention is that
>> in this form, it declares variables a, b and x that all occupy the same
>> location (the start of a 40-byte block).
>>
>> Then you can write x=1.0; and print out its bit pattern using a.
>>
>> There is another similar feature but that is not as tidy; I used to use
>> it like this:
>>
>> int64 c @ &b[4]
>>
>> where the b is the 10-int array. Now, c is a 64-bit value occupying the
>> same location as b[4] and b[5].
>>
>> So you can do sharing of memory, and read it in whichever way you like.
>> You have to use a different identifier for each type, but that is better.
>
> In CAlive, I allow every variable to be referenced by its name prefixed
> with an underscore, which is the unsigned int equivalent of whatever type
> it is. It does not require a union, but allows everything to be used as
> an unsigned integer of its bytes, used for passing things around, setting
> things without casting, etc.
I do low-level programming all the time, and it is extremely rare for me
to need such access. For more "normal" programming, it would be even
less useful. I think it is good for a language to have some way of
accessing the low-level data, but I can't see it as something common
enough to need this sort of syntax - it is just not a feature that
people will have significant use of. On the other hand, the use of _ as
a letter will be much, much more common, so this will lead to confusion.
It is good that a language can handle as many possibilities as you can
think of, but rare tasks can involve awkward or difficult coding. In
fact, a task like this /should/ involve awkward coding - it is not an
operation that people should carry out lightly or do unnecessarily. To
me, it would make much more sense to have a function like:
read_as_uint32_t(x);
In C, you often use the memcpy() function for this sort of access - it
looks awkward, but the compiler can normally turn it into optimal
assembly and keep everything in registers without needing memory
accesses at all.
>
> I am explicitly using it for pointers, and for function pointers, where
> the my_func() function is referenced as _my_func to reference its address.
>
> Thank you,
> Rick C. Hodgin
>
[toc] | [prev] | [next] | [standalone]
| From | John Bode <jfbode1029@gmail.com> |
|---|---|
| Date | 2017-06-12 07:26 -0700 |
| Message-ID | <2175c337-f0e7-43f8-8e1c-67e1f17ef8cb@googlegroups.com> |
| In reply to | #112012 |
On Monday, June 12, 2017 at 8:57:47 AM UTC-5, Rick C. Hodgin wrote:
> I came across this today. I had coded it this way by accident, but when
> I saw the error message it made me wonder why it's an error in C?
>
> const char y[] = "Y";
>
> void example(void)
> {
> char x;
>
> x = derive_x_from_something();
>
> if (x[0] == y[0])
> {
> // Code here for match
> }
> }
>
> In this case, I'm comparing x[0] to y[0]. Obviously y[0] works just
> fine, but the C compiler complained about x[0], giving the error:
>
> Microsoft's C Compiler for Visual Studio 2010
> C2109, "subscript requires array or pointer type"
>
> Obviously c is a char, but isn't it also, by definition, an array of
> exactly one element?
No, it is not, at least not as far as C is concerned. The language
definition clearly distinguishes between scalar types and aggregate types.
Besides, the operand of the [] operator *must* be a pointer type, which x
clearly is not.
> Why wouldn't x[0] be valid? I could use this
> and have it work:
>
> if (((char *)&x)[0] == y[0])
> {
> // Code here for match
> }
>
> In this case it doesn't change anything at all, but the reference is
> then resolvable to the compiler because it's looking at the same single
> byte through the new lens of a pointer type, rather than a single char.
>
> It just struck me as odd because CAlive will recognize single variables
> as arrays of exactly one element, and even do bounds checking on their
> references at compile time.
That's how *your* language works. That's not how C works.
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-12 10:54 -0400 |
| Message-ID | <70f7fb10-9ea8-1ea8-c5f2-299a4aad447f@verizon.net> |
| In reply to | #112017 |
On 06/12/2017 10:26 AM, John Bode wrote:
> On Monday, June 12, 2017 at 8:57:47 AM UTC-5, Rick C. Hodgin wrote:
>> I came across this today. I had coded it this way by accident, but when
>> I saw the error message it made me wonder why it's an error in C?
>>
>> const char y[] = "Y";
>>
>> void example(void)
>> {
>> char x;
>>
>> x = derive_x_from_something();
>>
>> if (x[0] == y[0])
>> {
>> // Code here for match
>> }
>> }
>>
>> In this case, I'm comparing x[0] to y[0]. Obviously y[0] works just
>> fine, but the C compiler complained about x[0], giving the error:
>>
>> Microsoft's C Compiler for Visual Studio 2010
>> C2109, "subscript requires array or pointer type"
>>
>> Obviously c is a char, but isn't it also, by definition, an array of
>> exactly one element?
>
> No, it is not, at least not as far as C is concerned. The language
> definition clearly distinguishes between scalar types and aggregate types.
He's probably getting confused about 6.5.6p7, which describes the binary
+ and - operators: "For the purposes of these operators, a pointer to an
object that is not an element of an array behaves the same as a pointer
to the first element of an array of length one with the type of the
object as its element type."
So, he's off by one level of indirection. It's quite true that a pointer
to x is treated (for the purposes of those operators) as a pointer to an
array consisting of a single 'char'. However, x itself is not such an
array, and because it isn't such an array, does not automatically
convert into a pointer to the first element of that array.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-12 09:23 -0700 |
| Message-ID | <lnr2ypgood.fsf@kst-u.example.com> |
| In reply to | #112025 |
"James R. Kuyper" <jameskuyper@verizon.net> writes:
[...]
> He's probably getting confused about 6.5.6p7, which describes the binary
> + and - operators: "For the purposes of these operators, a pointer to an
> object that is not an element of an array behaves the same as a pointer
> to the first element of an array of length one with the type of the
> object as its element type."
>
> So, he's off by one level of indirection. It's quite true that a pointer
> to x is treated (for the purposes of those operators) as a pointer to an
> array consisting of a single 'char'.
A pointer to the initial element of such an array, not a pointer to the
array itself.
> However, x itself is not such an
> array, and because it isn't such an array, does not automatically
> convert into a pointer to the first element of that array.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Gareth Owen <gwowen@gmail.com> |
|---|---|
| Date | 2017-06-12 19:05 +0100 |
| Message-ID | <87a85daxpb.fsf@gmail.com> |
| In reply to | #112017 |
John Bode <jfbode1029@gmail.com> writes: > That's how *your* language works. That's not how C works. That's how his language might conceivably work one day.
[toc] | [prev] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@gmail.com> |
|---|---|
| Date | 2017-06-12 17:29 +0300 |
| Message-ID | <20170612172931.b3ebbc7b90a0f9a8c35b4330@gmail.com> |
| In reply to | #112012 |
Rick C. Hodgin:
> I came across this today. I had coded it this way
> by accident, but when I saw the error message it
> made me wonder why it's an error in C?
>
> const char y[] = "Y";
>
> void example(void)
> {
> char x;
>
> x = derive_x_from_something();
>
> if (x[0] == y[0])
> {
> // Code here for match
> }
> }
>
> In this case, I'm comparing x[0] to y[0]. Obvi-
> ously y[0] works just fine, but the C compiler
> complained about x[0], giving the error:
>
> Microsoft's C Compiler for Visual Studio 2010
> C2109, "subscript requires array or pointer
> type"
>
> Obviously c is a char, but isn't it also, by defi-
> nition, an array of exactly one element?
Since you are working on a human-oriented language,
I shall answer from that point. x is not an array
of characters with a single element for exactly the
same reason that it is not a three-dimensional array
of characters, a set of characters, a list of char-
acters, a threaded binary tree of characters, or a
all those container structures one within another.
This reflects well different concepts in the human
brain. A box with a potato is not a potato but a
box.
> I could use this and have it work:
>
> if (((char *)&x)[0] == y[0])
> {
> // Code here for match
> }
>
> In this case it doesn't change anything at all,->
But it does. Instead of working with x as with a
character, you break the type system by taking its
address in memory and treating that as an array of
characters.
> -> but the reference is then resolvable to the
> compiler because it's looking at the same single
> byte through the new lens of a pointer type,
> rather than a single char.
This is also redundant and hides the true nature x.
Why not keep things as simple from the human point
of view as may be and never confuse boxes and po-
toes?
--
() ascii ribbon campaign -- against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-12 15:52 +0100 |
| Message-ID | <87ink1cl6y.fsf@bsb.me.uk> |
| In reply to | #112012 |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com> writes: <snip> > char x; <snip> > if (((char *)&x)[0] == y[0]) You are converting a char * to a char *. (&x)[0] would do just fine. <snip> > It just struck me as odd because CAlive will... Ah, there we go. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2017-06-12 08:31 -0700 |
| Message-ID | <c2060453-b175-42db-89e8-2f249cc3df1c@googlegroups.com> |
| In reply to | #112024 |
On Monday, June 12, 2017 at 10:52:47 AM UTC-4, Ben Bacarisse wrote: > "Rick C. Hodgin" <rick.c.hodgin@gmail.com> writes: > > It just struck me as odd because CAlive will... > Ah, there we go. To save time for your future posts, all of the things I do with regards to both C and C++ these days are governed by the light and focus I have in moving toward CAlive. I have no intention to stay with C or C++ forever. But, I am still there today, and until I am able to boostrap my own code base, to then never look back (at least not until I come back to add C89/C99 support), I must dwell in this place and seek out the assistance of others who are the true experts in C. Thank you, Rick C. Hodgin
[toc] | [prev] | [next] | [standalone]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-06-13 22:09 -0700 |
| Message-ID | <9f667a41-7a36-4cf4-9286-f1df3781dff4@googlegroups.com> |
| In reply to | #112012 |
On Monday, June 12, 2017 at 10:57:47 PM UTC+9, Rick C. Hodgin wrote:
> I came across this today. I had coded it this way by accident, but when
> I saw the error message it made me wonder why it's an error in C?
>
> const char y[] = "Y";
>
> void example(void)
> {
> char x;
>
> x = derive_x_from_something();
>
> if (x[0] == y[0])
> {
> // Code here for match
> }
> }
>
> In this case, I'm comparing x[0] to y[0]. Obviously y[0] works just
> fine, but the C compiler complained about x[0], giving the error:
There is something called a mathematical grammar here that has to be
satisfied before the compiler can recognize any meaning in the source
text, much less produce any meaningful result (thus, code).
According to the grammar of C, you named x as a scalar of type char.
If you want to treat x as an array of one character, you must use the
grammar of C to say that you want to do so:
(&x)[ 0 ] = y[ 0 ]
should do the trick.
C does allow you to say x[0] about a scalar in some cases (which I had
forgotten until recently), but what it will want to do if you say that
is something like this, IIRC:
((unsigned long) x)[0]
In other words, it would attempt to treat x as a pointer. So, if x has
the ASCII value of 'A' (decimal 65, or hexadecimal 0x41), it would try
to add 0 to 65 to get a memory address.
(That is, it would, if this were one of the cases where this interpretation
is allowed. It isn't, so it won't. It will just complain.)
> Microsoft's C Compiler for Visual Studio 2010
> C2109, "subscript requires array or pointer type"
>
> Obviously c is a char, but isn't it also, by definition, an array of
> exactly one element?
But you have to go to the trouble of looking at it as an array, to look
at it as an array.
> Why wouldn't x[0] be valid? I could use this
> and have it work:
>
> if (((char *)&x)[0] == y[0])
In this case you have gone to the trouble of telling the compiler you
want to see the scalar as if it were an element of an array. This is
what the grammar is for, to allow you to tell the compiler you want
to access the location by address, although the optimizer will hopefully
do away with the extra jumping through hoops.
> {
> // Code here for match
> }
>
> In this case it doesn't change anything at all,
Of course you have changed things. You haven't changed the data, but you
have changed the compiler's understanding of how it is to be referenced.
'A'[0]
is not the same thing as
'A'
and you have told the compiler that you want the 'A' or something like
it that is stored at x, not the data that 'A' or something like it
stored there would point at interpreted as a pointer.
> but the reference is
> then resolvable to the compiler because it's looking at the same single
> byte through the new lens of a pointer type, rather than a single char.
>
> It just struck me as odd because CAlive will recognize single variables
> as arrays of exactly one element, and even do bounds checking on their
> references at compile time.
If CAlive is to be able to do such things, I think it must be run on a
processor that has an RPM instruction, because it has to be able to figure
out whether it should treat x[0] as (if you will pardon M6809 assembler)
LDA X+0
or
LDA 0[X]
(RPM is the mnemonic we used to use for "Read Programmer's Mind".)
If x is a char, maybe it will work. But what happens when x is an
unsigned long?
> Thank you,
> Rick C. Hodgin
BTW, I spent a long time trying to figure out, given
char xarray[ SIZE ];
the difference between
char * ptr = xarray;
and
char ** pptr = &xarray;
and such, which are not easy to understand, relative to the address
operator. (Much of what the address operator does is compile-time
only, and never really seen in reasonably optimized object code, for
simple expressions like the above.)
I had to shift to arrays of ints and structs and of multi-dimensioned
arrays to get the concept firmly in my mind, and, as I demonstrated here
recently, I still have a hard time holding it in my mind.
I think the difficulty of that concept is no small part of the reason
most high-level language authors decide not to let the programmer work
directly with pointers the way C does.
--
Joel Rees
Trying to re-invent the computer industry all by myself;
http://defining-computers.blogspot.jp/
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-14 11:24 +0100 |
| Message-ID | <87wp8e9895.fsf@bsb.me.uk> |
| In reply to | #112162 |
joel.rees@gmail.com writes: <snip> > C does allow you to say x[0] about a scalar in some cases (which I had > forgotten until recently), but what it will want to do if you say that > is something like this, IIRC: > > ((unsigned long) x)[0] > > In other words, it would attempt to treat x as a pointer. So, if x has > the ASCII value of 'A' (decimal 65, or hexadecimal 0x41), it would try > to add 0 to 65 to get a memory address. Something has gone wrong here. Given the description, I think you meant to write ((unsigned long *)x)[0] whether that can (or will) access an unsigned long at address 65 is not something C has much to say about. It may work, it may not. It may even terminate your program! <snip> > 'A'[0] > > is not the same thing as > > 'A' > > and you have told the compiler that you want the 'A' or something like > it that is stored at x, not the data that 'A' or something like it > stored there would point at interpreted as a pointer. If we are still talking about C, the most significant distinction is that 'A'[0] is a contrast violation -- it must be diagnosed as an error and the implementation is then free to do whatever it likes. <snip> > BTW, I spent a long time trying to figure out, given > > char xarray[ SIZE ]; > > the difference between > > char * ptr = xarray; > > and > > char ** pptr = &xarray; > > and such, which are not easy to understand, relative to the address > operator. The latter is, again, a constraint violation. The type of pptr is char ** and the type of &xarray is char (*)[SIZE] These are not compatible types and an error must be reported. I'm not sure what you want to illustrate with this example so I can't say what you intended to write. <snip> -- Ben.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web