This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Clarifying attribute-const


Hello,

I'd like to ask for community input regarding __attribute__((const)) (and
"pure", where applicable).  My main goal is to clarify unclear cases and
improve existing documentation, if possible.

First, a belated follow-up to https://gcc.gnu.org/PR66512 . The bug is asking
why attribute-const appears to have a weaker effect in C++, compared to C.
The answer in that bug is that GCC assumes that attribute-const function can
terminate by throwing an exception.

That doesn't actually seem reasonable.  Consider that C counterpart to
throwing is longjmp; it seems to me that GCC should behave consistently:
either assume that attribute-const may both longjmp and throw (I guess nobody
wants that), or that it may not longjmp nor throw.  Intuitively, if "const"
means "free of side effects so that calls can be moved speculatively or
duplicated", then non-local control flow transfer via throwing should be
disallowed as well.

In any case, it would be nice the intended compiler behavior could be
explicitely stated in the manual.


Second, there is an interesting mismatch between documentation and existing
usage.  Among most prominent users of the attribute there are two glibc
functions: __errno_location(void) and pthread_self(void).  Both return a
pointer to thread-local storage, so the functions are not "const" globally in
a multi-threaded process.  A sufficiently advanced compiler can cause the
following testcase to abort:

#include <pthread.h>
#include <errno.h>

static void *errno_pointer;

static void *thr(void *unused)
{
  errno_pointer = &errno;
  return 0;
}

int main()
{
  errno_pointer = &errno;
  pthread_t t;
  pthread_create(&t, 0, thr, 0);
  pthread_join(t, 0);
  if (errno_pointer == &errno)
    abort();
}

(errno_pointer is static, so the compiler can observe that it does not escape
the translation unit, and all stores in the TU assign the same "const" value)

Does GCC need to be concerned about eventually "miscompiling" such cases?  If
not, can we document an explicit promise that attribute-const may include
pointers-to-TLS?

Thanks.
Alexander


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]