Re: C11, <stdatomic.h> and atomic pointers

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

 



On 05/01/2019 07:31 AM, Chris Hall wrote:

I find that:

   int * _Atomic foo ;
   int bar[12] ;

   foo = bar ;
   foo += 4 ;            // foo -> &bar[4] -- of course

   foo = bar ;
   atomic_fetch_add(&foo, 4) ;     // foo -> &bar[1] -- ????


I think this is a bug 64843:
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64843

which, I confess, I did not quite expect.  (Happy I looked, though !)

So, I looked at the Standard:

   7.17.7.5 The atomic_fetch and modify generic functions

   1 The following operations perform arithmetic and bitwise
     computations. All of these operations are applicable to an
     object of any atomic integer type. None of these
     operations is applicable to atomic_bool.

Of course, "integer type" excludes pointers, so I guess what it does with pointers is undefined.

Should gcc be throwing a friendly warning here ?

But the Standard goes on to say:

   3 ... For signed integer types ... there are no undefined
     results. ...
     ... For address types, the result may be an undefined
     address, but the operations otherwise have no undefined
     behavior.

I don't know why it feels the need to mention "address types", given that they are not valid arguments ?  [I'm assuming that by "address types" it actually means "pointer types".  I can find no other mention of "address type".]

Yes, that's a problem in the standard text that should be fixed.

The "Synopsis" says:

   2 #include <stdatomic.h>
     <C> atomic_fetch_<key>(volatile <A> *object, <M> operand);
     <C> atomic_fetch_<key>_explicit(volatile <A> *object,
                               <M> operand, memory_order order);

and the meaning of <A>, <C> and <M> is given in "7.17.1 Introduction", as follows:

   5 In the following synopses:

      - An <A> refers to one of the atomic types.
      - A <C> refers to its corresponding non-atomic type.
      - An <M> refers to the type of the other argument for
        arithmetic operations. For atomic integer types, <M>
        is <C>. For atomic pointer types, <M> is ptrdiff_t.

As it happens, <M> only used in the Synopsis for atomic_fetch_<key>... which is not defined for pointer types ?

I realise this is not really the place for discussion of the Standard, but I assume that what gcc does is based on some interpretation of it. Is there a good place to look for that interpretation ?

There are C defect reports that GCC also considers.  Some may
already be incorporated, others are not.  C11 defect reports
are tracked here:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm

If the above isn't being tracked there or in the list below
we might want write up a new issue for it and submit it to
WG14 to get it fixed in C2X.
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2316.htm

Martin


Chris

--------------------------

FWIW (1): the functions in gcc/glibc's <stdatomic.h> do *not* require the various <A> arguments to be atomic types... they are perfectly happy with ordinary types.  That doesn't seem right to me.

FWIW (2): the Standard (later in 7.17.7.5) says:

   5 NOTE The operation of the atomic_fetch and modify generic
     functions are nearly equivalent to the operation of the
     corresponding op= compound assignment operators. The only
     differences are that the compound assignment operators are
     not guaranteed to operate atomically, ...

Except that "6.5.16.2 Compound assignment" says:

   3 A compound assignment of the form E1 op= E2 ...
     ... If E1 has an atomic type, compound assignment is a
     read-modify-write operation with memory_order_seq_cst
     memory order semantics.

which looks like a flat contradiction to me.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux