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


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

Casts on lvalues

Started by"BartC" <bc@freeuk.com>
First post2012-12-02 13:23 +0000
Last post2012-12-07 16:54 +0000
Articles 17 on this page of 77 — 21 participants

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


Contents

  Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-02 13:23 +0000
    Re: Casts on lvalues SG <sgesemann@gmail.invalid> - 2012-12-02 14:40 +0100
    Re: Casts on lvalues Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-02 13:53 +0000
      Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-06 12:26 +0000
        Re: Casts on lvalues Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-06 15:15 +0000
        Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-06 12:05 -0800
    Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-02 12:34 -0800
      Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-02 21:18 +0000
        Re: Casts on lvalues Willem <willem@turtle.stack.nl> - 2012-12-05 22:36 +0000
          Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 23:46 +0000
            Re: Casts on lvalues Willem <willem@turtle.stack.nl> - 2012-12-06 18:35 +0000
      Re: Casts on lvalues pete <pfiland@mindspring.com> - 2012-12-02 16:21 -0500
        Re: Casts on lvalues Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-02 17:10 -0500
          Re: Casts on lvalues pete <pfiland@mindspring.com> - 2012-12-02 18:50 -0500
        Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-02 19:14 -0500
    Re: Casts on lvalues falk@rahul.net (Edward A. Falk) - 2012-12-04 23:57 +0000
      Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 01:35 +0000
        Re: Casts on lvalues Piotr Kalinowski <pitkali@gmail.com> - 2012-12-05 16:07 +0100
          Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 16:47 +0000
            Re: Casts on lvalues Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-05 13:04 -0500
              Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 18:39 +0000
                Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-05 14:23 -0500
                  Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 22:11 +0000
                    Re: Casts on lvalues Ian Collins <ian-news@hotmail.com> - 2012-12-06 11:51 +1300
                      Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 23:58 +0000
                        Re: Casts on lvalues Piotr Kalinowski <pitkali@gmail.com> - 2012-12-06 22:00 +0100
                    Re: Casts on lvalues glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-06 03:05 +0000
                Re: Casts on lvalues Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-05 14:43 -0500
                Re: Casts on lvalues Greg Martin <greg@softsprocket.com> - 2012-12-05 12:25 -0800
                  Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 21:57 +0000
                    Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-05 16:09 -0800
                      Re: Casts on lvalues Philipp Thomas <kthomas@linux01.gwdg.de> - 2012-12-07 01:24 +0100
                        Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-06 17:22 -0800
                          Re: Casts on lvalues Öö Tiib <ootiib@hot.ee> - 2012-12-07 00:31 -0800
                            Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-07 08:18 -0500
                              Re: Casts on lvalues Öö Tiib <ootiib@hot.ee> - 2012-12-07 09:07 -0800
                            Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-07 11:01 -0800
                              Re: Casts on lvalues glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-07 21:57 +0000
                                Re: Casts on lvalues Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-07 22:29 +0000
                                  Re: Casts on lvalues glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-08 00:04 +0000
                              Re: Casts on lvalues lawrence.jones@siemens.com - 2012-12-15 16:51 -0500
                                Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-15 15:48 -0800
                                  Re: Casts on lvalues lawrence.jones@siemens.com - 2012-12-17 16:37 -0500
                              Re: Casts on lvalues Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 02:58 -0800
                            Re: Casts on lvalues Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 02:53 -0800
                          Re: Casts on lvalues Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 02:43 -0800
                Re: Casts on lvalues Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-05 22:07 +0000
                  Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-05 22:20 +0000
                    Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-05 16:10 -0800
                    Re: Casts on lvalues Philip Lantz <prl@canterey.us> - 2012-12-06 22:49 -0800
                      Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-07 12:54 +0000
                        Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-07 08:22 -0500
                          Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-07 13:48 +0000
                            Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-07 11:17 -0500
                              Re: Casts on lvalues glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-07 17:33 +0000
                                Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-07 18:28 +0000
                                  Re: Casts on lvalues glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-07 22:18 +0000
                              Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-07 18:27 +0000
                                Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-07 14:14 -0500
                                  Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-07 20:16 +0000
                                    Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-07 15:41 -0500
                                      Re: Casts on lvalues Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 03:03 -0800
                Re: Casts on lvalues Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-12-09 17:54 +0200
                  Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-09 12:38 -0500
                    Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-09 18:50 +0000
                      Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-09 14:31 -0500
                        Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-09 20:12 -0800
                          Re: Casts on lvalues Heikki Kallasjoki <fis+usenet@zem.fi> - 2012-12-10 07:38 +0000
                            Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-10 08:12 -0500
                              Re: Casts on lvalues Heikki Kallasjoki <fis+usenet@zem.fi> - 2012-12-10 17:46 +0000
                                Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-10 12:59 -0500
                                Re: Casts on lvalues Keith Thompson <kst-u@mib.org> - 2012-12-10 12:07 -0800
                              Re: Casts on lvalues Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 03:11 -0800
                          Re: Casts on lvalues Ian Collins <ian-news@hotmail.com> - 2012-12-10 20:50 +1300
                          Re: Casts on lvalues James Kuyper <jameskuyper@verizon.net> - 2012-12-10 07:49 -0500
    Re: Casts on lvalues Rui Maciel <rui.maciel@gmail.com> - 2012-12-07 15:19 +0000
      Re: Casts on lvalues "BartC" <bc@freeuk.com> - 2012-12-07 16:54 +0000

Page 4 of 4 — ← Prev page 1 2 3 [4]


#29045

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-12-07 15:41 -0500
Message-ID<50C2547E.30609@verizon.net>
In reply to#29042
On 12/07/2012 03:16 PM, BartC wrote:
> "James Kuyper" <jameskuyper@verizon.net> wrote in message 
> news:50C24019.1020505@verizon.net...
...
>> I'm not talking about all optimizations, just the ones that depend upon
>> C's anti-aliasing guarantees. Consider the following function:
>>
>>    void func(int n, float array[static n], long *l)
>>    {
>>        for(int i=0; i<n; i++)
>>            array[i] = *l;
>>        *l = n;
>>    }
> 
>> An implementation is permitted, because of 6.5p7, to compile that
>> function as if it had been written:
> 
>>    void func(int n, float array[static n], long *l)
>>    {
>>        long temp = *l;
>>        for(int i=0; i<n; i++)
>>            array[i] = temp;
>>        *l = n;
>>    }
>>
>> The optimized version has exactly the same behavior as the original, so
>> long as 6.5p7 is not violated. If C were changed to allow a long integer
>> to be equivalenced with a element of a float array, the value of *l
>> might change during the loop.
> 
> (Seems like it might just be copied to itself? In this example).

I think you're assuming that sizeof(long)==sizeof(float), which is
commonplace, but not required. However, even on systems where that is
true, the result is not a simple copy. The conversion to float will
produce a bit pattern that's pretty unlikely to be the same as the
original (unless the original represents 0).

>  >If so, these two versions of the code
>> would no longer be equivalent, and there's an important question to be
>> asked about which one actually matches the user's intent. If the initial
>> value of *l was carefully chosen with the intent that it would, in fact,
>> be changed by this code inside that loop, the developer is going to be a
>> little upset if that didn't actually happen.
> 
> I can't see that the problems are going to be that different from the ones 
> you might get when using pointers. (And the solutions might be similar.)

In C, such code using pointer casts violates 6.5p7, and therefore has
undefined behavior, so the solution is simply not to write such code.

> Because even without equivalencing, 'l' might anyway point into the array, 
> via a cast.

Not with defined behavior.

> If this was part of the language, at least the aliasing would be done in an 
> overt manner, not hidden away in a pointer cast, in an operation done at 
> runtime so you don't know at any time what is aliasing what.

As I said, the C language does provide a way to explicitly alias objects
of two different types, and the optimizations I've described above are
therefore prohibited when they occur within the scope of a union
declaration that connects the relevant types (except in those contexts
where the compiler can be certain that the relevant pointers do not
point at members of the same union object).

[toc] | [prev] | [next] | [standalone]


#29390

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-17 03:03 -0800
Message-ID<kfnpq29hrff.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29045
James Kuyper <jameskuyper@verizon.net> writes:

> On 12/07/2012 03:16 PM, BartC wrote:
>> "James Kuyper" <jameskuyper@verizon.net> wrote in message 
>> news:50C24019.1020505@verizon.net...
> ...
>>> I'm not talking about all optimizations, just the ones that depend upon
>>> C's anti-aliasing guarantees. Consider the following function:
>>>
>>>    void func(int n, float array[static n], long *l)
>>>    {
>>>        for(int i=0; i<n; i++)
>>>            array[i] = *l;
>>>        *l = n;
>>>    }
>> 
>>> An implementation is permitted, because of 6.5p7, to compile that
>>> function as if it had been written:
>> 
>>>    void func(int n, float array[static n], long *l)
>>>    {
>>>        long temp = *l;
>>>        for(int i=0; i<n; i++)
>>>            array[i] = temp;
>>>        *l = n;
>>>    }
>>>
>>> The optimized version has exactly the same behavior as the original, so
>>> long as 6.5p7 is not violated. If C were changed to allow a long integer
>>> to be equivalenced with a element of a float array, the value of *l
>>> might change during the loop.
>> 
>> (Seems like it might just be copied to itself? In this example).
>
> I think you're assuming that sizeof(long)==sizeof(float), which is
> commonplace, but not required. However, even on systems where that is
> true, the result is not a simple copy. The conversion to float will
> produce a bit pattern that's pretty unlikely to be the same as the
> original (unless the original represents 0).
>
>>  >If so, these two versions of the code
>>> would no longer be equivalent, and there's an important question to be
>>> asked about which one actually matches the user's intent. If the initial
>>> value of *l was carefully chosen with the intent that it would, in fact,
>>> be changed by this code inside that loop, the developer is going to be a
>>> little upset if that didn't actually happen.
>> 
>> I can't see that the problems are going to be that different from the ones 
>> you might get when using pointers. (And the solutions might be similar.)
>
> In C, such code using pointer casts violates 6.5p7, and therefore has
> undefined behavior, so the solution is simply not to write such code.
>
>> Because even without equivalencing, 'l' might anyway point into the array, 
>> via a cast.
>
> Not with defined behavior.
>
>> If this was part of the language, at least the aliasing would be done in an 
>> overt manner, not hidden away in a pointer cast, in an operation done at 
>> runtime so you don't know at any time what is aliasing what.
>
> As I said, the C language does provide a way to explicitly alias objects
> of two different types, and the optimizations I've described above are
> therefore prohibited when they occur within the scope of a union
> declaration that connects the relevant types [snip unimportant exception].

I think you'd get some disagreement on this last point.  It
is not enough that the types in question just co-reside in a 
visible union type.  If that were true there would be no reason
for the "special rule" about struct's and accessing their
common prefix.

[toc] | [prev] | [next] | [standalone]


#29097

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2012-12-09 17:54 +0200
Message-ID<878v97kyqq.fsf@bazspaz.fatphil.org>
In reply to#28951
"BartC" <bc@freeuk.com> writes:
> "Eric Sosman" <esosman@comcast-dot-net.invalid> wrote:
...
> >> I asked about doing the same on the left side of an assignment.
> >>
> >> It's this asymmetry that is the issue.
> >
> >     Um, er, assignment itself is asymmetric ...
> 
> Plenty of terms can appear interchangeably on both left and right sides.
> 
> But while A can appear on either side, (T)A can't. And there doesn't
> appear to be a convincing reason why not.

Your posts are getting more and more detached from reality. What would 

  (T)A = expr;

even mean? What is getting modified? Certainly A can't be. One could argue
that some temporary non-addressible pseudo-object containing the cast value
of A is being modified, but as that pseudo-object fails to be referenceable 
after that line, the assignment is absolutely useless.

I want neither meaninglessness nor uselessness as a language feature.

Phil
-- 
I'm not saying that google groups censors my posts, but there's a strong link
between me saying "google groups sucks" in articles, and them disappearing.

Oh - I guess I might be saying that google groups censors my posts.

[toc] | [prev] | [next] | [standalone]


#29099

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-12-09 12:38 -0500
Message-ID<ka2ibh$kau$1@dont-email.me>
In reply to#29097
On 12/09/2012 10:54 AM, Phil Carmody wrote:
> "BartC" <bc@freeuk.com> writes:
>> "Eric Sosman" <esosman@comcast-dot-net.invalid> wrote:
> ...
>>>> I asked about doing the same on the left side of an assignment.
>>>>
>>>> It's this asymmetry that is the issue.
>>>
>>>     Um, er, assignment itself is asymmetric ...
>>
>> Plenty of terms can appear interchangeably on both left and right sides.
>>
>> But while A can appear on either side, (T)A can't. And there doesn't
>> appear to be a convincing reason why not.
> 
> Your posts are getting more and more detached from reality. What would 
> 
>   (T)A = expr;
> 
> even mean? What is getting modified? Certainly A can't be. One could argue
> that some temporary non-addressible pseudo-object containing the cast value
> of A is being modified, but as that pseudo-object fails to be referenceable 
> after that line, the assignment is absolutely useless.
> 
> I want neither meaninglessness nor uselessness as a language feature.

He's made it clear what he wants it to mean. What he wants is equivalent
to the following C code, except for the fact that the following code
violates a constraint, and he wants this construct to have well-defined
behavior:

    *(T*)&A = expr;

That this construct would have such a meaning is inconsistent with the
way casts work in the rest of the C language, which doesn't bother him;
in fact, I think he believes it's inconsistent for it to NOT work this
way. It would still be a horrible unsafe thing to do, even if it were
fully legal. It can be done somewhat more safely by declaring a union,
but he wants to be able to use it even in contexts where he can't change
the definition of A to be a union, and the syntax for doing it using a
union is more complicated than he wants it to be. Also, he thinks the
syntax to do this using a union is excessively complicated.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#29100

From"BartC" <bc@freeuk.com>
Date2012-12-09 18:50 +0000
Message-ID<Y75xs.794968$A%.108803@fx26.am4>
In reply to#29099
"James Kuyper" <jameskuyper@verizon.net> wrote in message
news:ka2ibh$kau$1@dont-email.me...
> On 12/09/2012 10:54 AM, Phil Carmody wrote:

>> Your posts are getting more and more detached from reality. What would
>>
>>   (T)A = expr;

>> I want neither meaninglessness nor uselessness as a language feature.

(Neither do I.)

> He's made it clear what he wants it to mean.

>    *(T*)&A = expr;

> It can be done somewhat more safely by declaring a union,
> but he wants to be able to use it even in contexts where he can't change
> the definition of A to be a union, and the syntax for doing it using a
> union is more complicated than he wants it to be. Also, he thinks the
> syntax to do this using a union is excessively complicated.

It's not that complicated, but it's intrusive.

It would also affect uses of 'A' throughout the project. (And perhaps a
different module might want to apply a different union!) Sometimes you might
just want to use such a cast locally. Or it might be experimental, and you 
want to try out something without turning the whole project upside-down.

There are plenty of uses for the feature. And if a union-like behaviour is
the way to do it, perhaps the compiler can take care of it, in trivial
cases. Or the rules for unions can be relaxed. So instead of having to
change;

S* p;

to:

union {
 S* s;
 T* t;
} p;

and changing every p to p.s or p.t, simpler to allow an anonymous union, for
example:

union {
 S* p;
};

Now p can be used as before, but the compiler knows there might be aliasing
issues. This still requires the cast. Or:

union {
 S* p;
 T* pt;
};

Now p is only changed in a few places to pt, instead of using a cast. (As a
bonus, it would be nice to augment an existing union too.)

-- 
Bartc

 

[toc] | [prev] | [next] | [standalone]


#29101

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-12-09 14:31 -0500
Message-ID<ka2ovb$1ji$1@dont-email.me>
In reply to#29100
On 12/09/2012 01:50 PM, BartC wrote:
...
> There are plenty of uses for the feature. And if a union-like behaviour is
> the way to do it, perhaps the compiler can take care of it, in trivial
> cases. Or the rules for unions can be relaxed. So instead of having to
> change;
> 
> S* p;
> 
> to:
> 
> union {
>  S* s;
>  T* t;
> } p;
> 
> and changing every p to p.s or p.t, simpler to allow an anonymous union, for
> example:
> 
> union {
>  S* p;
> };

That wouldn't do anything useful. It doesn't tell the compiler which
other types p is aliased with, so it can't know how much space to
reserve for the union, nor what alignment requirements the union will have.

> Now p can be used as before, but the compiler knows there might be aliasing
> issues. This still requires the cast. Or:
> 
> union {
>  S* p;
>  T* pt;
> };

That, on the other hand, would work, and is trivially compatible with
the current C language. Anonymous unions are already allowed as members
in structures (as of C2011), and stand-alone anonymous unions have, I
believe, long been a common extension to C.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#29103

FromKeith Thompson <kst-u@mib.org>
Date2012-12-09 20:12 -0800
Message-ID<lnr4mymto6.fsf@nuthaus.mib.org>
In reply to#29101
James Kuyper <jameskuyper@verizon.net> writes:
> On 12/09/2012 01:50 PM, BartC wrote:
[...]
>> union {
>>  S* p;
>>  T* pt;
>> };
>
> That, on the other hand, would work, and is trivially compatible with
> the current C language. Anonymous unions are already allowed as members
> in structures (as of C2011), and stand-alone anonymous unions have, I
> believe, long been a common extension to C.

I think you may be mistaken on that last point.

Are you saying that (with such an extension), this:

    union {
        unsigned u;
        float f;
    };
    f = 1.0;
    printf("0x%x\n", u);

would be allowed?  I haven't seen that; gcc warns "unnamed
struct/union that defines no instances".  In other words, a
standalone anonymous union is already valid but useless.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#29105

FromHeikki Kallasjoki <fis+usenet@zem.fi>
Date2012-12-10 07:38 +0000
Message-ID<ka43hs$olu$1@dont-email.me>
In reply to#29103
On 2012-12-10, Keith Thompson <kst-u@mib.org> wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>> the current C language. Anonymous unions are already allowed as members
>> in structures (as of C2011), and stand-alone anonymous unions have, I
>> believe, long been a common extension to C.
>
> I think you may be mistaken on that last point.
>
> Are you saying that (with such an extension), this:
>
>     union {
>         unsigned u;
>         float f;
>     };
>     f = 1.0;
>     printf("0x%x\n", u);
>
> would be allowed?  I haven't seen that; gcc warns "unnamed
> struct/union that defines no instances".  In other words, a
> standalone anonymous union is already valid but useless.

At least from C99 onwards, I don't think it's "already valid"; based on
the constraint in C99 6.7p2:

  A declaration shall declare at least a declarator (other than the
  parameters of a function or the members of a structure or union), a
  tag, or the members of an enumeration.

It would therefore be a non-conflicting extension to assign some
compiler-specific meaning on such code.  (Though I have not come across
such an extension anywhere either.)

-- 
Heikki Kallasjoki

[toc] | [prev] | [next] | [standalone]


#29120

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-12-10 08:12 -0500
Message-ID<ka4n40$tqo$1@dont-email.me>
In reply to#29105
On 12/10/2012 02:38 AM, Heikki Kallasjoki wrote:
> On 2012-12-10, Keith Thompson <kst-u@mib.org> wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>>> the current C language. Anonymous unions are already allowed as members
>>> in structures (as of C2011), and stand-alone anonymous unions have, I
>>> believe, long been a common extension to C.
>>
>> I think you may be mistaken on that last point.
>>
>> Are you saying that (with such an extension), this:
>>
>>     union {
>>         unsigned u;
>>         float f;
>>     };
>>     f = 1.0;
>>     printf("0x%x\n", u);
>>
>> would be allowed?  I haven't seen that; gcc warns "unnamed
>> struct/union that defines no instances".  In other words, a
>> standalone anonymous union is already valid but useless.
> 
> At least from C99 onwards, I don't think it's "already valid"; based on
> the constraint in C99 6.7p2:
> 
>   A declaration shall declare at least a declarator (other than the
>   parameters of a function or the members of a structure or union), a
>   tag, or the members of an enumeration.
> 
> It would therefore be a non-conflicting extension to assign some
> compiler-specific meaning on such code.  (Though I have not come across
> such an extension anywhere either.)

As I said, it's "already allowed as members in structures (as of
C2011)", not C99. See 6.7.2.1p13: "an unnamed member whose type
specifier is a union specifier with no tag is called an anonymous
union.", where "anonymous union" is italicized, indicating that this
sentence serves to define that term.

However, they don't seem to have made a corresponding change to 6.7p2. I
don't see any way to interpret it that's compatible with the anonymous
structure and union members that were added in C2011. That may have been
an oversight - hopefully Larry Jones can comment?
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#29130

FromHeikki Kallasjoki <fis+usenet@zem.fi>
Date2012-12-10 17:46 +0000
Message-ID<ka5762$4o1$1@dont-email.me>
In reply to#29120
On 2012-12-10, James Kuyper <jameskuyper@verizon.net> wrote:
> On 12/10/2012 02:38 AM, Heikki Kallasjoki wrote:
>> On 2012-12-10, Keith Thompson <kst-u@mib.org> wrote:
>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>> the current C language. Anonymous unions are already allowed as members
>>>> in structures (as of C2011), and stand-alone anonymous unions have, I
>>>> believe, long been a common extension to C.
>>>
>>> I think you may be mistaken on that last point.
>>>
>>> Are you saying that (with such an extension), this:
>>>
>>>     union {
>>>         unsigned u;
>>>         float f;
>>>     };
>>>     f = 1.0;
>>>     printf("0x%x\n", u);
>>>
>>> would be allowed?  I haven't seen that; gcc warns "unnamed
>>> struct/union that defines no instances".  In other words, a
>>> standalone anonymous union is already valid but useless.
                                  ^^^^^^^^^^^^^
>> At least from C99 onwards, I don't think it's "already valid"; based on
>> the constraint in C99 6.7p2:
[..]
>
> As I said, it's "already allowed as members in structures (as of
> C2011)", not C99. See 6.7.2.1p13: "an unnamed member whose type

It was, however, the highlighted instance of "already valid" from Keith
Thompson that I was commenting on; the one considering the standalone
case.

(Apologies for the confusion.)

-- 
Heikki Kallasjoki

[toc] | [prev] | [next] | [standalone]


#29132

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-12-10 12:59 -0500
Message-ID<50C62309.7030907@verizon.net>
In reply to#29130
On 12/10/2012 12:46 PM, Heikki Kallasjoki wrote:
> On 2012-12-10, James Kuyper <jameskuyper@verizon.net> wrote:
>> On 12/10/2012 02:38 AM, Heikki Kallasjoki wrote:
>>> On 2012-12-10, Keith Thompson <kst-u@mib.org> wrote:
>>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>>> the current C language. Anonymous unions are already allowed as members
>>>>> in structures (as of C2011), and stand-alone anonymous unions have, I
>>>>> believe, long been a common extension to C.
>>>>
>>>> I think you may be mistaken on that last point.
>>>>
>>>> Are you saying that (with such an extension), this:
>>>>
>>>>     union {
>>>>         unsigned u;
>>>>         float f;
>>>>     };
>>>>     f = 1.0;
>>>>     printf("0x%x\n", u);
>>>>
>>>> would be allowed?  I haven't seen that; gcc warns "unnamed
>>>> struct/union that defines no instances".  In other words, a
>>>> standalone anonymous union is already valid but useless.
>                                   ^^^^^^^^^^^^^
>>> At least from C99 onwards, I don't think it's "already valid"; based on
>>> the constraint in C99 6.7p2:
> [..]
>>
>> As I said, it's "already allowed as members in structures (as of
>> C2011)", not C99. See 6.7.2.1p13: "an unnamed member whose type
> 
> It was, however, the highlighted instance of "already valid" from Keith
> Thompson that I was commenting on; the one considering the standalone
> case.
> 
> (Apologies for the confusion.)

It was my confusion - your wording was clear enough. I'm not sure how I
managed to misread it that way. I remember looking for, and not finding,
the word 'valid' in the preceding text, so I must not have been fully
awake when I performed that search. Therefore, I keyed in on the only
use of 'already' that I could find (another indication that I wasn't
fully awake).

[toc] | [prev] | [next] | [standalone]


#29135

FromKeith Thompson <kst-u@mib.org>
Date2012-12-10 12:07 -0800
Message-ID<ln8v95n024.fsf@nuthaus.mib.org>
In reply to#29130
Heikki Kallasjoki <fis+usenet@zem.fi> writes:
> On 2012-12-10, James Kuyper <jameskuyper@verizon.net> wrote:
>> On 12/10/2012 02:38 AM, Heikki Kallasjoki wrote:
>>> On 2012-12-10, Keith Thompson <kst-u@mib.org> wrote:
>>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>>> the current C language. Anonymous unions are already allowed as members
>>>>> in structures (as of C2011), and stand-alone anonymous unions have, I
>>>>> believe, long been a common extension to C.
>>>>
>>>> I think you may be mistaken on that last point.
>>>>
>>>> Are you saying that (with such an extension), this:
>>>>
>>>>     union {
>>>>         unsigned u;
>>>>         float f;
>>>>     };
>>>>     f = 1.0;
>>>>     printf("0x%x\n", u);
>>>>
>>>> would be allowed?  I haven't seen that; gcc warns "unnamed
>>>> struct/union that defines no instances".  In other words, a
>>>> standalone anonymous union is already valid but useless.
>                                   ^^^^^^^^^^^^^
>>> At least from C99 onwards, I don't think it's "already valid"; based on
>>> the constraint in C99 6.7p2:
> [..]
>>
>> As I said, it's "already allowed as members in structures (as of
>> C2011)", not C99. See 6.7.2.1p13: "an unnamed member whose type
>
> It was, however, the highlighted instance of "already valid" from Keith
> Thompson that I was commenting on; the one considering the standalone
> case.
>
> (Apologies for the confusion.)

Your statement was both sufficiently clear and correct; a standalone
anonymous union is *not* valid in C99 (i.e., I was mistaken).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#29391

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-17 03:11 -0800
Message-ID<kfnlicxhr14.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29120
James Kuyper <jameskuyper@verizon.net> writes:

> On 12/10/2012 02:38 AM, Heikki Kallasjoki wrote:
>> On 2012-12-10, Keith Thompson <kst-u@mib.org> wrote:
>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>> the current C language. Anonymous unions are already allowed as members
>>>> in structures (as of C2011), and stand-alone anonymous unions have, I
>>>> believe, long been a common extension to C.
>>>
>>> I think you may be mistaken on that last point.
>>>
>>> Are you saying that (with such an extension), this:
>>>
>>>     union {
>>>         unsigned u;
>>>         float f;
>>>     };
>>>     f = 1.0;
>>>     printf("0x%x\n", u);
>>>
>>> would be allowed?  I haven't seen that; gcc warns "unnamed
>>> struct/union that defines no instances".  In other words, a
>>> standalone anonymous union is already valid but useless.
>> 
>> At least from C99 onwards, I don't think it's "already valid"; based on
>> the constraint in C99 6.7p2:
>> 
>>   A declaration shall declare at least a declarator (other than the
>>   parameters of a function or the members of a structure or union), a
>>   tag, or the members of an enumeration.
>> 
>> It would therefore be a non-conflicting extension to assign some
>> compiler-specific meaning on such code.  (Though I have not come across
>> such an extension anywhere either.)
>
> As I said, it's "already allowed as members in structures (as of
> C2011)", not C99. See 6.7.2.1p13: "an unnamed member whose type
> specifier is a union specifier with no tag is called an anonymous
> union.", where "anonymous union" is italicized, indicating that this
> sentence serves to define that term.
>
> However, they don't seem to have made a corresponding change to 6.7p2. I
> don't see any way to interpret it that's compatible with the anonymous
> structure and union members that were added in C2011. That may have been
> an oversight - hopefully Larry Jones can comment?

6.7p2 applies to declarations.  The elements defining the contents
of a struct (or union) type, including anonymous structs (or unions)
are struct-declarations, not declarations.  6.7p2 doesn't apply.

[toc] | [prev] | [next] | [standalone]


#29106

FromIan Collins <ian-news@hotmail.com>
Date2012-12-10 20:50 +1300
Message-ID<ailihnFq3nrU1@mid.individual.net>
In reply to#29103
Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>> On 12/09/2012 01:50 PM, BartC wrote:
> [...]
>>> union {
>>>   S* p;
>>>   T* pt;
>>> };
>>
>> That, on the other hand, would work, and is trivially compatible with
>> the current C language. Anonymous unions are already allowed as members
>> in structures (as of C2011), and stand-alone anonymous unions have, I
>> believe, long been a common extension to C.
>
> I think you may be mistaken on that last point.
>
> Are you saying that (with such an extension), this:
>
>      union {
>          unsigned u;
>          float f;
>      };
>      f = 1.0;
>      printf("0x%x\n", u);
>
> would be allowed?  I haven't seen that; gcc warns "unnamed
> struct/union that defines no instances".  In other words, a
> standalone anonymous union is already valid but useless.

Sun cc is a little less subtle:
warning: useless declaration

What did surprise me is the code appears to be valid C++!  I guess you 
learn something new every day.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#29118

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-12-10 07:49 -0500
Message-ID<ka4lph$m19$1@dont-email.me>
In reply to#29103
On 12/09/2012 11:12 PM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>> On 12/09/2012 01:50 PM, BartC wrote:
> [...]
>>> union {
>>>  S* p;
>>>  T* pt;
>>> };
>>
>> That, on the other hand, would work, and is trivially compatible with
>> the current C language. Anonymous unions are already allowed as members
>> in structures (as of C2011), and stand-alone anonymous unions have, I
>> believe, long been a common extension to C.
> 
> I think you may be mistaken on that last point.
> 
> Are you saying that (with such an extension), this:
> 
>     union {
>         unsigned u;
>         float f;
>     };
>     f = 1.0;
>     printf("0x%x\n", u);
> 
> would be allowed?  I haven't seen that; gcc warns "unnamed
> struct/union that defines no instances".  In other words, a
> standalone anonymous union is already valid but useless.

They are permitted and useful in C++; that may be what I was thinking of.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#29020

FromRui Maciel <rui.maciel@gmail.com>
Date2012-12-07 15:19 +0000
Message-ID<k9t1e6$o0i$1@dont-email.me>
In reply to#28872
BartC wrote:

> Suppose I have these types:
> 
> #define byte unsigned char
> 
> typedef struct {
>  int a,b,c,d;
> } R;               /* assume this is 16 bytes */

R stores 4 objects of type int, whose size is platform-dependent.  If you 
need a 4-byte integer data type then your best bet would be on int32_t, 
which gives you the assurance that you will get an integer data type which 
is exactly 32-bit wide.


> And these variables:
> 
> int n;             /* represents a *byte* offset */

If you wish to represent a byte offset then you should use size_t instead.


> R* p;
> 
> I want to be able to do the following:
>  p += n;
> 
> but it doesn't work because n is a byte offset; it's not in terms of R
> objects. 

I don't know what yo were trying to do, but if you were trying to access the 
offset of a structure member by supplying the address of the struct then you 
should use the offsetof() command instead of relying on pointer arithmetic 
voodoo. 


> But the obvious cast:
> 
>  (byte*)p+=n;
> 
> doesn't appear to compile.  

Try


> The workarounds seem to be:
> 
>  p += n/sizeof(R);
> 
> which I don't like. 

You shouldn't.  No one should.  It represents all kinds of badness.


> Even though p is always aligned (and n is known to be
> a multiple of 16), 

How do you know that p is always aligned, and that n is a multipleof 16? 
Each non-bit-field member of a struct is aligned in an implementation-
defined manner, which means that there isn't any guarantee regarding the 
alignment of the structure members.  

In addition, padding may or may not exist.  

Finally, R was defined as a struct composed of 4 objects of type int, and 
the int data type may be 8 or 16-bit wide depending on the implementation. 


> and I know the divide will cancel out, it seems funny
> having to introduce a divide op in the first place. And:
> 
>  p = (R*)((byte*)p+n);
> 
> which is what I'm using but looks very untidy in real code.
> 
> In any case, the question remains, *is* there a way to cast an lvalue as
> I've shown above?

What exactly were you trying to accomplish with that code?  It's rather odd 
that someone tries to assign a pointer to a structure to the n-th member of 
a struct of the same type.


Rui Maciel

[toc] | [prev] | [next] | [standalone]


#29024

From"BartC" <bc@freeuk.com>
Date2012-12-07 16:54 +0000
Message-ID<3cpws.786984$vW7.181918@fx19.am4>
In reply to#29020
"Rui Maciel" <rui.maciel@gmail.com> wrote in message 
news:k9t1e6$o0i$1@dont-email.me...
> BartC wrote:

>> Even though p is always aligned (and n is known to be
>> a multiple of 16),
>
> How do you know that p is always aligned

p points into a malloc-allocated array of such structs.

>> , and that n is a multipleof 16?

Because all such values (originally +2, -1 etc) have been multiplied by 16 
(or rather, sizeof(R)) in an initial pass of the data!

>>  p = (R*)((byte*)p+n);

> What exactly were you trying to accomplish with that code?  It's rather 
> odd
> that someone tries to assign a pointer to a structure to the n-th member 
> of
> a struct of the same type.

p points into an array of structs. It's modified to point instead at a +2 
or -1 etc offset from where it currently is.

But I decided to change that +2, -1 etc to +32, -16 etc because I didn't 
like the 80 million extra left-shifts being executed every second for no 
purpose.

-- 
Bartc 

[toc] | [prev] | [standalone]


Page 4 of 4 — ← Prev page 1 2 3 [4]

Back to top | Article view | comp.lang.c


csiph-web