bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Bug in C compiler Compiler Bug for Case 3411658RE (fwd)


From: Martin MOKREJŠ
Subject: RE: Bug in C compiler Compiler Bug for Case 3411658RE (fwd)
Date: Mon, 28 Apr 2003 20:48:08 +0200 (CEST)

---------- Forwarded message ----------
From: "Belgardt, Wolfgang" <address@hidden>
To: Martin MOKREJŠ <address@hidden>
Date: Mon, 28 Apr 2003 16:19:28 +0200
Subject: RE: Bug in C compiler Compiler Bug for Case   3411658RE (fwd)

Hello Mr. Mokrejs,

My  engineering colleagues  have talk together and they have send the following 
answer.
The program still violates that C99 standard, but for a different       reason

>From C99:

6.3.1.2 Boolean type
   (1) When any scalar value is converted to _Bool, the result
       is 0 if the value compares equal to 0; otherwise, the
       result is 1.

6.2.5 Types
  (21) Arithmetic types and pointer types are collectively
       called scalar types.

6.7.8 Initialization (Constraints, so violation mandates a diagnostic)
   (4) All the expressions in an initializer for an object
       that has static storage duration shall be constant
       expressions or string literals.

6.6 Constant expressions
   (7) More latitude is permitted for constant expressions in
       initializers.  Such a constant expression shall be,
       or evaluate to, one of the following:
        - an arithmetic constant expression,
        - a null pointer constant,
        - an address constant,
        - an address constant for an object type plus or minus an
          integer constant expression.

   (8) An arithmetic constant expression shall have arithmetic
       type and shall only have operands that are integer constants,
       floating constants, enumeration constants, character
       constants, and sizeof expressions.  Cast operators in
       an arithmetic constant expression shall only convert
       arithmetic type to arithmetic types, except as part
       of an operand to a sizeof operator whose result is
       an integer constant.

   (9) An address constant is a null pointer, a pointer to
       an lvalue designating an object of static storage
       duration, or a pointer to a function designator;
       it shall be created explicitly using the unary &
       operator or an integer constant cast to pointer type,
       or implicitly by the use of an expression of array or
       function type.  The array-subscript [] and member-access
       . and -> operators, the address & and indirection *
       unary operators, and pointer casts may be used
       in the creation of an address constant, but the
       value of an object shall not be accessed by use
       of these operators.

The construct at hand involves an initializer for an
object with static storage duration, so it is a
constraint that the expression be a constant expression
or a string literal.  Since it isn't a string literal,
it must be one of the "relaxed" forms of constant
expression enumerated in 6.6(7).  (_Bool)&foo is clearly
not a null pointer constant, an address constant, or
an address constant for an object type plus or minus
an integer constant expression.  Therefore it can
only statisfy the constraint if it is an arithmetic
constant expression.  But it is not an arithmetic
constant expression because it contains an operand,
&foo, that is not an integer constant, floating constant,
enumeration constant, character constant, or a sizeof
expression.  And even if &foo were considered to be
an arithmetic constant expression, (_Bool)&foo would
still not be an arithmetic constant expression because
it contains a cast that does not convert from one
arithmetic type to another.

So the expression (_Bool)&foo violates a constraint
if it is used as an initializer for an object
of static storage duration, and a strictly-conforming
implementation must issue a diagnostic.

Informally, note that the definition of converting a
scalar value to type _Bool requires that the value
be compared to 0.  Since the address of an object
with static storage duration is not known until
link time, producing the correct result requires
that the compare operation happen at link time
or later.  So either the object module language
and linker would need to support such a comparison
operator, or else the comparison must be done at
run-time during some kind of "init" phase.  This is
not a problem for C++, which requires support for
run-time innitialization of objects with static
storage duration, but the C99 language does not
require such support.  And many/most? object
languages and linkers do not support a comparison
operator.  Thus producing the correct result
for this initialization would place a new and
unique requirement on the C implementation that
is not needed for any other feature in the language.

A possible response to the practical consideration
above is that since &foo requires a declaration of
foo, and a declaration used in an expression requires
that a definition exist somewhere in the compilation
units of the program, and that a pointer to an
object that exists is not a null pointer, and a
pointer value that compares equal to 0 is a null
pointer, then a compiler could simply evaluate the
expression as 1 without requiring any link-time
or run-time evaluation.  However, in the realm of
practical considerations, it should be noted that
it is a common practice on some platforms to use
weak symbol references to determine whether or
not a given "optional" module has been linked
into a program; typically the address of such a
weak symbol will be zero if the module is not
present: an expression such as (_Bool)&foo would
be a sensible construct to use to determine whether
or not the module defining foo had been linked
in - having the compiler treat it as a compile-time
constant 1 would defeat that practical usage.

Bottom line: formally it is a constaint violation.
And practically producing the practically correct
result places a burden on the C implementation
that is not needed by any other construct in
the C99 language.


Mit freundlichen Grüssen / Kind Regards


Wolfgang Belgardt
Customer Support Consultant

Hewlett-Packard GmbH
Customer Support
Bonsiepen 5
D-45136 Essen
Phone: ++49 (0) 201 2663 258
Fax:             ++49 (0) 201 2663 200
mobil:    +49 (0171 3357 256)
E-mail:  address@hidden
http://www.hp.com/de
__________________________________________________________________________________
Hewlett-Packard GmbH
Geschäftsführer: Jörg Menno Harms (Vorsitzender), Jürgen Banhardt, Wolfram 
Fischer,
 Rainer Kaczmarczyk, Bärbel Schmidt, Fritz Schuller, Regine Stachelhaus
Vorsitzender des Aufsichtsrats: Heribert Schmitz
Sitz der Gesellschaft: Böblingen, Amtsgericht Böblingen HRB 4081

-----Original Message-----
From: Martin MOKREJ© [mailto:address@hidden
Sent: Friday, April 25, 2003 11:51
To: Belgardt, Wolfgang
Subject: Re: Bug in C compiler Compiler Bug for Case 3411658RE (fwd)

Could you please forward?

--
Martin Mokrejs <address@hidden>, <address@hidden>
PGP5.0i key is at http://www.natur.cuni.cz/~mmokrejs
MIPS / Institute for Bioinformatics <http://mips.gsf.de>
GSF - National Research Center for Environment and Health
Ingolstaedter Landstrasse 1, D-85764 Neuherberg, Germany
tel.: +49-89-3187 3683 , fax: +49-89-3187 3585

---------- Forwarded message ----------
From: Paul Eggert <address@hidden>
To: Martin MOKREJ© <address@hidden>
Cc: address@hidden
Date: 24 Apr 2003 13:55:45 -0700
Subject: Re: Bug in C compiler Compiler Bug for Case   3411658RE (fwd)

Martin MOKREJ(c) <address@hidden> writes:

> So, what to do now? ;)

Please refer them to section 6.3.1.2 of the C99 standard, which states:

    When any scalar value is converted to _Bool, the
    result is 0 if the value compares equal to 0;
    otherwise, the result is 1.

You can also refer them to HP's own documentation:

   When any scalar value is converted to _Bool, the result is 0 if the
   value compares equal to 0 (for example, if the pointer is
   NULL). Otherwise, the result is 1. This is one way the _Bool type is
   different than the other integer types.
   <http://h30097.www3.hp.com/dtk/Compaq_C_Compiler/doc/lrm/DOCU0006.HTM>


> From: "Belgardt, Wolfgang" <address@hidden>
> Date: Thu, 24 Apr 2003 15:14:14 +0200

>   To quote from the C99 standard,
>       section 6.3.2.3 (conversions involving pointers), paragraph 6 states:
>
>       "Any pointer type may be converted to an integer type.  Except as
>        previously specified, the result is implementation defined.  If the
>       result cannot be represented in the integer type, the behavior is
>       undefined."
>
>       As a _Bool can not hold the values of an address the Standard clearly
>       defines this as undefined behavior.

The behavior is undefined only if it is not "previously specified".
Section 6.3.1.2 provides the "previous specification" in this case.

>       There is no ability in Tru64 to tell the linker/loader "If
>       this symbol is defined deposit a 1 here, if not put a zero
>       here".

I don't see why that capability is needed.  The address of an object
is always non-NULL, so if x is an object then (_Bool)&x always
evaluates to 1.  HP doesn't need to modify its linker/loader to handle
this case.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]