[Gllug] C function strcasecmp

Nix nix at esperi.demon.co.uk
Mon Jul 30 07:23:46 UTC 2001


On Sun, 29 Jul 2001, home at alexhudson.com gibbered:
> On Sun, Jul 29, 2001 at 06:44:40PM +0100, Nix wrote:
>> >> > > 	*x+=~(*x)++;
>> >> > 
>> >> > Foul and invokes undefined behaviour; multiple modifications with no
>> >> > intervening sequence points ;P
>> > Actually, thinking about it - who cares if it's out of sequence? Doesn't
>> > matter :) (I think - assuming it wasn't being calculated in parallel,
>> > anyway).
>> 
>> You misunderstand the meaning of `undefined'. It doesn't mean
>> *anything*; it's not in C. The compiler is quite within its rights to
>> generate code that reformats the disk, or that runs nethack; it doesn't
>> just affect order-of-execution.
> 
> I don't think it is within it's rights to do that. The only issue here is
> the postincrement, surely?

It's time for me to get picky and put on my comp.std.c hat. The issue
here is (from the last public C99 draft; I haven't bought the standard
yet)

,----[ 6.3 ]
|        [#2] Between the previous and next sequence point an  object
|        shall  have  its  stored  value modified at most once by the
|        evaluation of an expression.  Furthermore, the  prior  value
|        shall  be  accessed  only  to  determine  the  value  to  be
|        stored.57
`----

(Non-normative footnote 57 makes it doubly clear that it is undefined
 what happens if this is not the case, but this is not actually
 necessary to make it undefined; see below.)

Undefined behaviour? That's this:

,----[ 3.18 Undefined behavior ]
|        [#1] Behavior,  upon  use  of  a  nonportable  or  erroneous
|        program  construct, of erroneous data, or of indeterminately
|        valued  objects,  for  which  this  International   Standard
|        imposes  no  requirements.   Permissible  undefined behavior
|        ranges  from  ignoring   the   situation   completely   with
|        unpredictable  results,  to  behaving  during translation or
|        program execution in a documented manner  characteristic  of
|        the   environment   (with  or  without  the  issuance  of  a
|        diagnostic  message),  to  terminating  a   translation   or
|        execution (with the issuance of a diagnostic message).
|
|        [#2] If  a  ``shall''  or  ``shall  not''  requirement  that
|        appears outside of a constraint is violated, the behavior is
|        undefined.  Undefined behavior  is  otherwise  indicated  in
|        this   International   Standard  by  the  words  ``undefined
|        behavior'' or by the omission of any explicit definition  of
|        behavior.   There  is  no difference in emphasis among these
|        three; they all describe ``behavior that is undefined.''
`----

Note particularly the wide range of things that `permissible undefined
behaviour' can be. The standard `imposes no requirements'. The compiler
can do *anything* (even optimize on the basis that `you can't have meant
to say that because it was undefined; maybe you meant *this* instead';
and, yes, there are compilers that do that). `Unpredictable results'
ranges wide, and the Standard doesn't actually impose any explicit
limits on what it may do (it only gives three *examples*).

> Which is a non-issue in this instance. Given the
> code compiles cleanly, even -Wall -pedantic, I think that pretty much makes
> it valid C.

Oh no. -Wall -ansi -pedantic doesn't come *close* to diagnosing all
constraint violations in the C Standard (some are impossible to
diagnose, in any case, or very, very hard, like violations of rules as
important as the One Definition Rule).

The GCC manual states

,----
| Some users try to use `-pedantic to check programs for strict ISO
| C conformance.  They soon find that it does not do quite what they want:
| it finds some non-ISO practices, but not all---only those for which
| ISO C *requires* a diagnostic, and some others for which diagnostics
| have been added.
| 
| A feature to report any failure to conform to ISO C might be useful in
| some instances, but would require considerable additional work and would
| be quite different from `-pedantic'.  We don't have plans to support
| such a feature in the near future.
`----

(but there have been joky mentions of a `-fconfound-me' switch for
portability testing, which makes GCC act as differently from normal as
the Standard allows... nobody's started implementing it; it would be an
invasive evil bastard, in any case. Far better just to build your code
with more than one compiler.)

>             I disagree with your definition of undefined in this instance
> also - while that could apply to APIs, I don't see how that applies to
> language constructs. I also can't find any reference to that definition in
> the C standards - where did you find it?

s3.18, the definition of the word `undefined' :) it's a very common
definition in standards, because if the standard doesn't define
something how *can* it impose constraints?

>> (Also, think what would happen if `x' needed multiple instructions to
>> address, there was a carry, and the system reordered execution so that
>> the += was done (perhaps partially) before the addition.
> 
> I don't think that happens even in bigmath. We're surely only concerned with
> operator precedence here?

I'm concerned with the definition of undefined behaviour, really; but
that could well happen with types like, say, `long long' on IA32 (too
long for any native single-instruction operations on the machine of
discourse to manipulate).

-- 
`It's all about bossing computers around. Users have to say "please".
Programmers get to say "do what I want NOW or the hard disk gets it".'
                        -- Richard Heathfield on the nature of programming

-- 
Gllug mailing list  -  Gllug at linux.co.uk
http://list.ftech.net/mailman/listinfo/gllug




More information about the GLLUG mailing list