All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Naujoks <nautsch2@googlemail.com>
To: Ricard Wanderlof <ricard.wanderlof@axis.com>
Cc: "linux-mtd@lists.infradead.org" <linux-mtd@lists.infradead.org>
Subject: Re: gcc 4.5 and copy_flag in libubigen.c
Date: Tue, 15 Mar 2011 10:29:12 +0100	[thread overview]
Message-ID: <4D7F3168.9010300@googlemail.com> (raw)
In-Reply-To: <Pine.LNX.4.64.1103150930350.25520@lnxricardw.se.axis.com>

Am 15.03.2011 09:45, schrieb Ricard Wanderlof:
> 
> On Mon, 14 Mar 2011, Andre Naujoks wrote:
> 
>> I am compiling a board support package with mtd-utils-1.3.1.
>>
>> After a gcc update to version 4.5 on my host the build fails and it
>> tells me that:
>>
>> ./src/libubigen.c: In function 'ubigen_write_leb':
>> ./src/libubigen.c:204:19: error: operation on 'u->v->copy_flag' may be
>> undefined.
>>
>> This seems like a recently introduced warning by the new gcc version,
>> but because of the -Werror halts my build.
> 
>> // This is the part gcc 4.5 complains about
>> // ---------------------
>>
>>        if (action & MARK_AS_UPDATE) {
>>                u->v->copy_flag = (u->v->copy_flag)++;
>>        }
>>
>> // --------------------
>>
> 
> I can understand why gcc warns about this, the operation is undefined. I
> would think the problem is not with the pointer dereference, it is the
> way the copy flag is used both before and after the ++. What you have is
> 
>   foo = foo++;
> 
> which is an undefined operation, for the following reason. While
> 
>   foo++;
> 
> says that foo has one value before this operation and the value +1 after
> (the C standard talks about 'sequence points', i.e points in the code
> where all variables have well defined values),
> 
>   foo = foo++;
> 
> is ambiguous in that it is not clear whether the ++ takes place after
> the assignment or vice versa. Should the compiler bump the value of foo,
> but return the old value, assign it to foo, and then assign foo the
> incremented value, or increment the value, return the old value, and
> assign it to foo, in effect not changing the value?
> 
> It might have worked by chance on an older compiler that didn't notice
> the problem and consistently picked one of the two possibilities above
> (preferebly the first one); however, according to the C standard, once
> an operation becomes undefined all aspects of it become undefined so the
> compiler could technically stuff any value in foo (or none at all).
> 
> Anyhow, technicalities aside, it looks like someone made a mental error
> when simply trying to set the copy_flag. I'm fairly convinced that the
> author simply meant:
> 
>   (u->v->copy_flag)++;
> 
>> My question is this. If this is indeed just a flag, can I just set
>> copy_flag to 1 instead of incrementing it? Witout breaking anything?
> 
> It is (or perhaps was?) commonplace to set flags by incrementing them.
> I'm not sure why this is considered a good idea. Possibly because
> 
>   flag++;
> 
> looks more elegant and cool than
> 
>   flag = 1;
> 
> although the latter is most certainly faster; in the first case the
> value must be read, incremented and copied back to the variable. Of
> course, if the variable is in a register there's no real overhead, but
> most processors have fast ways of loading small immediate values so the
> latter version will probably be just as quick and not need more code
> either.
> 
> I don't know if it could have something to do with the machines on which
> Unix was originally written, that it was faster, or, more likely, used
> up less code space, to increment something than to load it with 1.
> 
> I would agree with you in principle, especially since the variable is
> called 'flag' something, then again, without a thorough understanding of
> what the flag is used for, someone could conceivably have decided to use
> it as a counter instead of a flag, but retain the name.
> 
> /Ricard

Thanks for the detailed answer. At least I learned something today :-).
Since this code is considered old and no longer used I was able to just
disable this part in the build without consequences (AFAICS).

Thanks a lot anyway. I really appreciate it.

Andre

      reply	other threads:[~2011-03-15  9:29 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-14 16:37 gcc 4.5 and copy_flag in libubigen.c Andre Naujoks
2011-03-14 17:53 ` Matthieu CASTET
2011-03-15  7:55   ` Andre Naujoks
2011-03-15  8:06     ` Artem Bityutskiy
2011-03-15  9:21       ` Andre Naujoks
2011-03-15  8:04 ` Artem Bityutskiy
2011-03-15  8:45 ` Ricard Wanderlof
2011-03-15  9:29   ` Andre Naujoks [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D7F3168.9010300@googlemail.com \
    --to=nautsch2@googlemail.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=ricard.wanderlof@axis.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.