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


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

Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type?

Started byJohn Reye <jononanon@googlemail.com>
First post2012-05-02 09:06 -0700
Last post2012-05-07 17:16 -0700
Articles 20 on this page of 31 — 10 participants

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


Contents

  Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-02 09:06 -0700
    Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? "In a very dark China Blue, China Blue condition." <chine.bleu@yahoo.com> - 2012-05-02 09:33 -0700
    Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-02 12:36 -0400
      Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-02 10:04 -0700
        Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-02 13:23 -0400
      Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 09:20 -0700
        Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 09:25 -0700
          Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 10:16 -0700
          Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 11:05 -0700
          Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-03 15:21 -0400
        Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 09:46 -0700
        Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Nobody <nobody@nowhere.com> - 2012-05-03 19:14 +0100
          Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 11:45 -0700
            Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Jens Gustedt <jens.gustedt@loria.fr> - 2012-05-03 21:05 +0200
              Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 12:14 -0700
              Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-03 15:16 -0400
                Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Lanarcam <lanarcam1@yahoo.fr> - 2012-05-03 21:56 +0200
                  Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-03 16:12 -0400
                    Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 13:45 -0700
                    Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Nobody <nobody@nowhere.com> - 2012-05-04 01:34 +0100
                Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Jens Gustedt <jens.gustedt@loria.fr> - 2012-05-03 22:32 +0200
              Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 12:10 -0700
                Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Keith Thompson <kst-u@mib.org> - 2012-05-03 16:14 -0700
              Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Tim Rentsch <txr@alumni.caltech.edu> - 2012-05-07 17:24 -0700
            Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-03 15:19 -0400
              Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? John Reye <jononanon@googlemail.com> - 2012-05-03 12:25 -0700
        Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-03 17:44 -0400
    Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Barry Schwarz <schwarzb@dqel.com> - 2012-05-02 12:35 -0700
      Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-05-02 14:40 -0700
      Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? James Kuyper <jameskuyper@verizon.net> - 2012-05-02 17:51 -0400
      Re: Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type? Tim Rentsch <txr@alumni.caltech.edu> - 2012-05-07 17:16 -0700

Page 1 of 2  [1] 2  Next page →


#20224 — Can *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type?

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-02 09:06 -0700
SubjectCan *common* struct-members of 2 different struct-types, that are the same for the first common members, be accessed via pointer cast to either struct-type?
Message-ID<37f36566-0b91-4ee4-9135-6890c7c8de7a@12g2000vba.googlegroups.com>
Assume identical common top struct members:

struct a {
  int i1;
  char c1;
  short sa1[3];
};

struct b {
  int i2;
  char c2;
  short sa2[3];

  int differ_here;
};


struct a tmp;



Are the following 2 line always equivalent (as in: yielding the same
lvalue) and allowed:

tmp.c1
((struct b*)&tmp)->c1

Thanks.
- John.

[toc] | [next] | [standalone]


#20225

From"In a very dark China Blue, China Blue condition." <chine.bleu@yahoo.com>
Date2012-05-02 09:33 -0700
Message-ID<chine.bleu-FB1640.09335002052012@news.x-privat.org>
In reply to#20224
In article <37f36566-0b91-4ee4-9135-6890c7c8de7a@12g2000vba.googlegroups.com>,
 John Reye <jononanon@googlemail.com> wrote:

> Are the following 2 line always equivalent (as in: yielding the same
> lvalue) and allowed:

Maybe not. The guarantee only applies to the first member. The work around is to 
make each first field itself the same struct:

    struct common {
        int i; char c;
    };

> struct a {
    struct common x1;
>   short sa1[3];
> };
> 
> struct b {
    struct common x2;
>   short sa2[3];
> 
>   int differ_here;
> };

> 
> tmp.x1.c
> ((struct b*)&tmp)->x2.c


&struct a = &struct a.x1
&struct b = &struct b.x2
so if &struct a = &struct b
    &struct a.x1 = &struct b.x2
    and typeof struct a.x1 = typeof struct b.x2 = typeof struct common
therefore for each f in struct common
    &struct a.x1.f = &struct b.x2.f

-- 
My name Indigo Montoya.      |    R'lyeh 38o57'6.5''S 102o51'16''E.
You flamed my father.        |       I'm whoever you want me to be.
Prepare to be spanked.       |  Annoying Usenet one post at a time.
Stop posting that!           |    At least I can stay in character.

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


#20226

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-02 12:36 -0400
Message-ID<4FA16280.6040703@verizon.net>
In reply to#20224
On 05/02/2012 12:06 PM, John Reye wrote:
> Assume identical common top struct members:
> 
> struct a {
>   int i1;
>   char c1;
>   short sa1[3];
> };
> 
> struct b {
>   int i2;
>   char c2;
>   short sa2[3];
> 
>   int differ_here;
> };
> 
> 
> struct a tmp;
> 
> 
> 
> Are the following 2 line always equivalent (as in: yielding the same
> lvalue) and allowed:
> 
> tmp.c1
> ((struct b*)&tmp)->c1

No, the behavior is undefined. It's not because the members might be a
different locations in the two structs; that's possible but unlikely.
The real reason is the anti-aliasing rules (6.5p7). Because those rules
make the behavior of such code undefined, the implementation is not
obligated to consider the possibility that an lvalue referring to a
"struct a" object refers to the same object as one that refers to a
"struct b" object. As a result, when implementing code such as the
following:

	tmp.c1 = 1;
	printf("%d\n", ((struct b*)&tmp)->c1);

An implementation is not required to notice that the printf() is
referring to the same object as the assignment statement. As a result,
it could, for instance, defer the writing the new value to tmp.c1 until
after executing the printf() call. That's pretty unlikely in this simple
case, but gets more likely in more complicated code when aggressive
optimization is turned on.

There's a special exception that allows you to access the "common
initial sequence" of any two struct types, using either struct type,
when they are both members of the same union (6.5.2.3p6):

	union ab
	{
		struct a one;
		struct b two;
	} pair;
	pair.one.c1 = 1
	printf("%d\n", pair.two.c1);

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


#20227

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-02 10:04 -0700
Message-ID<71778362-d6f6-415e-9521-3b1d712988de@l3g2000vbv.googlegroups.com>
In reply to#20226
On May 2, 6:36 pm, James Kuyper wrote:
> On 05/02/2012 12:06 PM, John Reye wrote:
>
> > Assume identical common top struct members:
>
> > struct a {
> >   int i1;
> >   char c1;
> >   short sa1[3];
> > };
>
> > struct b {
> >   int i2;
> >   char c2;
> >   short sa2[3];
>
> >   int differ_here;
> > };
>
> > struct a tmp;
>
> > Are the following 2 line always equivalent (as in: yielding the same
> > lvalue) and allowed:
>
> > tmp.c1
> > ((struct b*)&tmp)->c1
>
> No, the behavior is undefined. It's not because the members might be a
> different locations in the two structs; that's possible but unlikely.
> The real reason is the anti-aliasing rules (6.5p7). Because those rules
> make the behavior of such code undefined, the implementation is not
> obligated to consider the possibility that an lvalue referring to a
> "struct a" object refers to the same object as one that refers to a
> "struct b" object. As a result, when implementing code such as the
> following:
>
>         tmp.c1 = 1;
>         printf("%d\n", ((struct b*)&tmp)->c1);
>
> An implementation is not required to notice that the printf() is
> referring to the same object as the assignment statement. As a result,
> it could, for instance, defer the writing the new value to tmp.c1 until
> after executing the printf() call. That's pretty unlikely in this simple
> case, but gets more likely in more complicated code when aggressive
> optimization is turned on.
>
> There's a special exception that allows you to access the "common
> initial sequence" of any two struct types, using either struct type,
> when they are both members of the same union (6.5.2.3p6):
>
>         union ab
>         {
>                 struct a one;
>                 struct b two;
>         } pair;
>         pair.one.c1 = 1
>         printf("%d\n", pair.two.c1);

Ah thanks James. Your replies are always much appreciated.

By the way does the union trick also work, when the first part is
common, but the 2 diverge afterwards.
Example:

     struct a {
       int i1;
       char c1;
       short sa1[3];

       char u;
     };

     struct b {
       int i2;
       char c2;
       short sa2[3];

       int differ_here;
     };



        union ab
        {
                struct a one;
                struct b two;
        } pair;


The sizeof(union ab) will be the maximum value, of course.
So some union access-members (e.g. short structs), do not give me
access to the whole union (as described by the maximum struct). Right?

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


#20228

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-02 13:23 -0400
Message-ID<4FA16DAD.3010805@verizon.net>
In reply to#20227
On 05/02/2012 01:04 PM, John Reye wrote:
> On May 2, 6:36 pm, James Kuyper wrote:
>> On 05/02/2012 12:06 PM, John Reye wrote:
>>
>>> Assume identical common top struct members:
>>
>>> struct a {
>>>   int i1;
>>>   char c1;
>>>   short sa1[3];
>>> };
>>
>>> struct b {
>>>   int i2;
>>>   char c2;
>>>   short sa2[3];
>>
>>>   int differ_here;
>>> };
>>
>>> struct a tmp;
>>
>>> Are the following 2 line always equivalent (as in: yielding the same
>>> lvalue) and allowed:
>>
>>> tmp.c1
>>> ((struct b*)&tmp)->c1

Correction: that should be ->c2, presumably.

>> No, the behavior is undefined. It's not because the members might be a
>> different locations in the two structs; that's possible but unlikely.
>> The real reason is the anti-aliasing rules (6.5p7). Because those rules
>> make the behavior of such code undefined, the implementation is not
>> obligated to consider the possibility that an lvalue referring to a
>> "struct a" object refers to the same object as one that refers to a
>> "struct b" object. As a result, when implementing code such as the
>> following:
>>
>>         tmp.c1 = 1;
>>         printf("%d\n", ((struct b*)&tmp)->c1);

Same correction here.

>> An implementation is not required to notice that the printf() is
>> referring to the same object as the assignment statement. As a result,
>> it could, for instance, defer the writing the new value to tmp.c1 until
>> after executing the printf() call. That's pretty unlikely in this simple
>> case, but gets more likely in more complicated code when aggressive
>> optimization is turned on.
>>
>> There's a special exception that allows you to access the "common
>> initial sequence" of any two struct types, using either struct type,
>> when they are both members of the same union (6.5.2.3p6):
>>
>>         union ab
>>         {
>>                 struct a one;
>>                 struct b two;
>>         } pair;
>>         pair.one.c1 = 1
>>         printf("%d\n", pair.two.c1);

Correction: that should have been pair.two.c2.

> Ah thanks James. Your replies are always much appreciated.
> 
> By the way does the union trick also work, when the first part is
> common, but the 2 diverge afterwards.

It works for the entire initial common sequence, no matter how many
additional members either struct type has after the common part.
Corresponding members of the common sequence must have compatible types;
for bit-fields, they must also have the same width.

> Example:
> 
>      struct a {
>        int i1;
>        char c1;
>        short sa1[3];
> 
>        char u;
>      };
> 
>      struct b {
>        int i2;
>        char c2;
>        short sa2[3];
> 
>        int differ_here;
>      };
> 
> 
> 
>         union ab
>         {
>                 struct a one;
>                 struct b two;
>         } pair;
> 
> 
> The sizeof(union ab) will be the maximum value, of course.
> So some union access-members (e.g. short structs), do not give me
> access to the whole union (as described by the maximum struct). Right?

Correct.

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


#20295

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 09:20 -0700
Message-ID<bf0df0b2-c9e5-4306-8c7e-ea99f5346364@v22g2000yqm.googlegroups.com>
In reply to#20226
On May 2, 6:36 pm, James Kuyper  wrote:
> the implementation is not
> obligated to consider the possibility that an lvalue referring to a
> "struct a" object refers to the same object as one that refers to a
> "struct b" object. As a result, when implementing code such as the
> following:
>
>         tmp.c1 = 1;
>         printf("%d\n", ((struct b*)&tmp)->c1);
>
> An implementation is not required to notice that the printf() is
> referring to the same object as the assignment statement.


Hmmm... I think that would be one heck of a rubbish compiler (or more
precisely *optimizing* compiler)! ;)
If the standard allows that kind of stuff, then it simply is not
bullet-proof enough.

Because tmp occurs in both lines. Every compiler should notice that!

Even if I "obfuscate" like this:
         tmp.c1 = 1;
         char *cp = ((struct b*)&tmp);
         printf("%d\n", cp->c1);

I'd expect any compiler that gets it wrong, to be complete rubbish.
Why? Because it's an optimizer BUG.
Why?
Because any simple compiler, that does not optimize... get's it right!
And if any simple compiler get's it right, then any optimization must
guarantee to get it right as well.

I mean: if the C standard allows one to create optimizers that result
in such ... ummm... surprises (read: "rubbish"), then the standard is
faulty in my eyes.

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


#20300

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 09:25 -0700
Message-ID<0cfb5df2-c15c-4125-803e-38d5ec7ae3b5@m15g2000vbh.googlegroups.com>
In reply to#20295
In fact...

then any use of pointers at all would fail.
char a;
char *p;

a = 1;
*p = 2;
printf("%d", a);

This will never print 1, unless the compiler is buggy.


In the same spirit... any compiler that gets the following wrong is
buggy:

>
>         tmp.c1 = 1;
>         printf("%d\n", ((struct b*)&tmp)->c2);
>
> An implementation is not required to notice that the printf() is
> referring to the same object as the assignment statement. As a result,
> it could, for instance, defer the writing the new value to tmp.c1 until
> after executing the printf() call. That's pretty unlikely in this simple
> case, but gets more likely in more complicated code when aggressive
> optimization is turned on.

It's not complicated. Rather... I suspect it would be a optimizer-
compiler bug.

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


#20308

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 10:16 -0700
Message-ID<746eda8e-2cca-48ae-9029-749a3a941710@p6g2000yqi.googlegroups.com>
In reply to#20300
(where did my message go? OK I'll repost)


Ah I think I got carried away above. Sorry.

The main problem was that I was putting down possible optimizing
compilers, while the reality is, that this statement itself is bloody
bad, and should be avoided at all costs.

struct a tmp;
((struct b*)&tmp)->c2

Reason: one casts from one type to a completely different unrelated
type.
Rather one should use an common inner struct, for the common parts
within structs. That's a simple way of not getting bitten. ;)

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


#20311

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 11:05 -0700
Message-ID<2a7055c3-0de3-46a6-b936-54d18093337c@e9g2000yqm.googlegroups.com>
In reply to#20300
On May 3, 6:25 pm, John Reye wrote:
> In fact...
>
> then any use of pointers at all would fail.
> char a;
> char *p;
>
> a = 1;
> *p = 2;
> printf("%d", a);
>
> This will never print 1, unless the compiler is buggy.

Correction in 2nd line of code:
  char *p = &a;

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


#20333

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-03 15:21 -0400
Message-ID<4FA2DA9E.1070702@verizon.net>
In reply to#20300
On 05/03/2012 12:25 PM, John Reye wrote:
> In fact...
> 
> then any use of pointers at all would fail.
> char a;
> char *p;
> 
> a = 1;
> *p = 2;
> printf("%d", a);

How do you reach that conclusion? That use of pointers doesn't violate
the anti-aliasing rules.

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


#20304

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 09:46 -0700
Message-ID<a36f5960-2fc2-4ffe-af5a-282418a4627d@n5g2000vbf.googlegroups.com>
In reply to#20295
Ahh on the other hand, I might have gotten carried away here.

>         tmp.c1 = 1;
>         printf("%d\n", ((struct b*)&tmp)->c1);

I would always avoid something like this (not because of aliasing
rules, and compiler optimization), but because of the reasons given by
the mysterious 2nd poster (copied below) and because it's completely
unnecessary!

There is simply no need to do something like this. One can always
introduce an inner struct for the common part.
So in my above arguments, I forgot that I was arguing for something
that this is very very bad style anyway... to cast from type struct,
to a different type like that. So what I said about "rubbish
compiler's" is probably completely out of context. Sorry.


mysterious 2nd poster wrote:
> The guarantee only applies to the first member. The work around is to
> make each first field itself the same struct:
>
>     struct common {
>         int i; char c;
>     };
>
> > struct a {
>
>     struct common x1;>   short sa1[3];
> > };
>
> > struct b {
>
>     struct common x2;
>
> >   short sa2[3];
>
> >   int differ_here;
> > };
>
> > tmp.x1.c
> > ((struct b*)&tmp)->x2.c
>
> &struct a = &struct a.x1
> &struct b = &struct b.x2
> so if &struct a = &struct b
>     &struct a.x1 = &struct b.x2
>     and typeof struct a.x1 = typeof struct b.x2 = typeof struct common
> therefore for each f in struct common
>     &struct a.x1.f = &struct b.x2.f
>
> --
> My name Indigo Montoya.      |    R'lyeh 38o57'6.5''S 102o51'16''E.
> You flamed my father.        |       I'm whoever you want me to be.
> Prepare to be spanked.       |  Annoying Usenet one post at a time.
> Stop posting that!           |    At least I can stay in character.

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


#20314

FromNobody <nobody@nowhere.com>
Date2012-05-03 19:14 +0100
Message-ID<pan.2012.05.03.18.14.50.178000@nowhere.com>
In reply to#20295
On Thu, 03 May 2012 09:20:24 -0700, John Reye wrote:

>>         tmp.c1 = 1;
>>         printf("%d\n", ((struct b*)&tmp)->c1);
>>
>> An implementation is not required to notice that the printf() is
>> referring to the same object as the assignment statement.
> 
> Hmmm... I think that would be one heck of a rubbish compiler (or more
> precisely *optimizing* compiler)! ;)
> 
> If the standard allows that kind of stuff, then it simply is not
> bullet-proof enough.
> 
> Because tmp occurs in both lines. Every compiler should notice that!

The compiler is free to lose track of that information during
optimisation, and may well do so.

> Why? Because it's an optimizer BUG.

A bug is a failure to behave as documented, not a failure to behave
according to the intuition of some guy on usenet.

If it were otherwise, all compilers would have bugs, and those bugs would
be impossible to fix, as different people's intutions are different and
often contradictory.

> Why?
> Because any simple compiler, that does not optimize... get's it right!
> And if any simple compiler get's it right, then any optimization must
> guarantee to get it right as well.

The behaviour of a "simple" compiler does not form a part of the standard.

> I mean: if the C standard allows one to create optimizers that result
> in such ... ummm... surprises (read: "rubbish"), then the standard is
> faulty in my eyes.

Whether or not it is faulty "in your eyes" is irrelevant. The standard
is what it is.

The standard explicitly and intentionally facilitates optimisation, rather
than forcing the majority of real-world code to be suboptimal for the sake
of pathological cases. This is also why "const" and "volatile" were added
to C89 and "restrict" to C99, in spite of being completely unnecessary for
"simple" (i.e. non-optimising) compilers.

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


#20320

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 11:45 -0700
Message-ID<9d036dbd-a150-43ae-9877-337465e49562@v2g2000vbx.googlegroups.com>
In reply to#20314
On May 3, 8:14 pm, Nobody wrote:
> The compiler is free to lose track of that information during
> optimisation, and may well do so.

char a;
char *p = &a;

a = 1;
*p = 2;
printf("%d\n", a);

Does the C standard guarantee, that the value 2 will get printed in
the above code??
Thanks.

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


#20323

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-05-03 21:05 +0200
Message-ID<4FA2D6EC.2020400@loria.fr>
In reply to#20320
Am 05/03/2012 08:45 PM, schrieb John Reye:
> On May 3, 8:14 pm, Nobody wrote:
>> The compiler is free to lose track of that information during
>> optimisation, and may well do so.
> 
> char a;
> char *p = &a;
> 
> a = 1;
> *p = 2;
> printf("%d\n", a);
> 
> Does the C standard guarantee, that the value 2 will get printed in
> the above code??

no

for that you'd have to declare them

char volatile a;
char volatile *p = &a;

Jens


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


#20325

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 12:14 -0700
Message-ID<293455e2-f0e5-4ef2-af2c-7354b23ff6ea@n4g2000vbz.googlegroups.com>
In reply to#20323
Assume no volatile:

char a;
char *p = &a;

Does the C standard guarantee that the following will print 2? ->

a = 1, *p = 2, printf("%d\n", a);

Thanks.

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


#20327

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-03 15:16 -0400
Message-ID<4FA2D999.5010405@verizon.net>
In reply to#20323
On 05/03/2012 03:05 PM, Jens Gustedt wrote:
> Am 05/03/2012 08:45 PM, schrieb John Reye:
>> On May 3, 8:14 pm, Nobody wrote:
>>> The compiler is free to lose track of that information during
>>> optimisation, and may well do so.
>>
>> char a;
>> char *p = &a;
>>
>> a = 1;
>> *p = 2;
>> printf("%d\n", a);
>>
>> Does the C standard guarantee, that the value 2 will get printed in
>> the above code??
> 
> no

Why not? In the abstract machine those statements must be executed in
sequence. There's a sequence point at the end of each statement, which
means that side effects such as the change in value of a in the second
statement, must be complete by the time the value of 'a' is read by the
third statement.

> for that you'd have to declare them
> 
> char volatile a;
> char volatile *p = &a;

Why should that be necessary?

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


#20339

FromLanarcam <lanarcam1@yahoo.fr>
Date2012-05-03 21:56 +0200
Message-ID<4fa2e2e0$0$13223$426a74cc@news.free.fr>
In reply to#20327
Le 03/05/2012 21:16, James Kuyper a écrit :
> On 05/03/2012 03:05 PM, Jens Gustedt wrote:
>
>> for that you'd have to declare them
>>
>> char volatile a;
>> char volatile *p =&a;
>
> Why should that be necessary?

IMO, volatile is useful when and only when the variable
can be modified by a piece of code out of scope of
the compiler or by a separate IC, for instance:

- global variable modifiable by several threads in a
multithread OS.

- Global variable modifiable by an ISR.

- Memory mapped IC registers.

Is that correct?

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


#20342

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-05-03 16:12 -0400
Message-ID<4FA2E6C2.7070400@verizon.net>
In reply to#20339
On 05/03/2012 03:56 PM, Lanarcam wrote:
...
> IMO, volatile is useful when and only when the variable
> can be modified by a piece of code out of scope of
> the compiler or by a separate IC, for instance:
> 
> - global variable modifiable by several threads in a
> multithread OS.
> 
> - Global variable modifiable by an ISR.
> 
> - Memory mapped IC registers.
> 
> Is that correct?

You left out another important context: signal handlers. In fact, until
C2011 added working about threading, signal handlers were the only
purely internal C reason for needing volatile; all of the other possible
reasons were outside the scope of the standard.

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


#20346

FromJohn Reye <jononanon@googlemail.com>
Date2012-05-03 13:45 -0700
Message-ID<36f35919-f0b2-4e8f-ac27-c12c2da340af@l7g2000vbz.googlegroups.com>
In reply to#20342
On May 3, 10:12 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> On 05/03/2012 03:56 PM, Lanarcam wrote:
> ...
>
> > IMO, volatile is useful when and only when the variable
> > can be modified by a piece of code out of scope of
> > the compiler or by a separate IC, for instance:
>
> > - global variable modifiable by several threads in a
> > multithread OS.
>
> > - Global variable modifiable by an ISR.
>
> > - Memory mapped IC registers.
>
> > Is that correct?
>
> You left out another important context: signal handlers. In fact, until
> C2011 added working about threading, signal handlers were the only
> purely internal C reason for needing volatile; all of the other possible
> reasons were outside the scope of the standard.

Volatile is also useful, if you have a dummy variable for debugging
purposes. To prevent it from getting optimized away (as could occur if
you never read from that variable, but just look at it through the
debugger), just declare it volatile.

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


#20368

FromNobody <nobody@nowhere.com>
Date2012-05-04 01:34 +0100
Message-ID<pan.2012.05.04.00.34.01.753000@nowhere.com>
In reply to#20342
On Thu, 03 May 2012 16:12:50 -0400, James Kuyper wrote:

> You left out another important context: signal handlers. In fact, until
> C2011 added working about threading, signal handlers were the only
> purely internal C reason for needing volatile; all of the other possible
> reasons were outside the scope of the standard.

Not quite; volatile is also meaningful in conjunction with setjmp/longjmp.
7.13.2.1p3 says:

       [#3] All accessible objects  have  values  as  of  the  time
       longjmp  was  called,  except  that the values of objects of
       automatic storage duration that are local  to  the  function
       containing  the invocation of the corresponding setjmp macro
       that do not  have  volatile-qualified  type  and  have  been
       changed  between  the setjmp invocation and longjmp call are
       indeterminate.

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


Page 1 of 2  [1] 2  Next page →

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


csiph-web