Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #112012 > unrolled thread

Unexpected error on x[0] != y[0]

Started by"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
First post2017-06-12 06:57 -0700
Last post2017-06-14 11:24 +0100
Articles 19 on this page of 39 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  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]


#112167

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#112120

Frombartc <bc@freeuk.com>
Date2017-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]


#112122

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#112135

Frombartc <bc@freeuk.com>
Date2017-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]


#112139

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#112125

Fromsupercat@casperkitty.com
Date2017-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]


#112145

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-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]


#112163

FromReinhardt Behm <rbehm@hushmail.com>
Date2017-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]


#112171

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-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]


#112168

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#112017

FromJohn Bode <jfbode1029@gmail.com>
Date2017-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]


#112025

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-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]


#112050

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#112068

FromGareth Owen <gwowen@gmail.com>
Date2017-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]


#112018

FromAnton Shepelev <anton.txt@gmail.com>
Date2017-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]


#112024

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#112038

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2017-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]


#112162

Fromjoel.rees@gmail.com
Date2017-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]


#112172

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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