tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] Strange bug found?


From: K K
Subject: Re: [Tinycc-devel] Strange bug found?
Date: Thu, 20 Feb 2020 15:10:52 +0000

Thanks for the clarification, sounds plausible to me. The wish remains that a warning or an error message is displayed for undefined behaviour 😊

 

 

Von: Vincent Lefevre
Gesendet: Donnerstag, 20. Februar 2020 13:06
An: address@hidden
Betreff: Re: [Tinycc-devel] Strange bug found?

 

On 2020-02-20 07:08:48 +0000, K K wrote:
> am I wrong or is the following a bug in tinycc?

It may be a bug, but your example is based on undefined behavior
(see below), thus it is difficult to say (I mean that tcc does not
necessarily exploit the fact that this is undefined behavior, which
can explain why this works in general).

> I found this using the last git commit (btw. git repo is currently not working again) and also in official 0.9.27, both on Windows.
>
> The output of the follwing short code is:
> 10 = 10 = 9, but of course should be 10 = 10 = 10
> The position of the marked line "double d = 0;" does not change the wrong behaviour as long as it is before "double b[n];" Changing the line to "int i = 0;" leads to correct behaviour.
>
> #include <stdio.h>
> #define ARRAYSIZE(a) (1[&(a)] - (a))

This is syntactically equivalent to

#define ARRAYSIZE(a) ( *(&(a) + 1) - (a) )

The ISO C standard says in 6.5.3.2p4:

  The unary * operator denotes indirection. If the operand points to
  a function, the result is a function designator; if it points to
  an object, the result is an lvalue designating the object. If the
  operand has type “pointer to type”, the result has type “type”. If
  an invalid value has been assigned to the pointer, the behavior of
  the unary * operator is undefined.

The issue is that &(a) + 1 points to the end of the array, which is
neither a function, nor an object. Even though the * operator will
not read any value here, the conditions of the C standard are not
satisfied.

and this is confirmed by the end of 6.5.6p8 (about the + operator):

  If the result points one past the last element of the array object,
  it shall not be used as the operand of a unary * operator that is
  evaluated.

> void main() {
>   double a[10];
>   size_t n = 10;
>   double d = 0; // <-- no failure if this is removed
>   double b[n];
>   printf("%u = %u = %u\n", ARRAYSIZE(a), n,   ARRAYSIZE(b));

Note that you should cast the 3 values to unsigned int.

> }
>
> Sincerely,
> Kernel

Regards,

--
Vincent Lefèvre <address@hidden> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

_______________________________________________
Tinycc-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

 


reply via email to

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