This is the mail archive of the gcc-patches@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]

Re: builtin_constant_p


This patch looks OK to me.

+	  /* Only emit CONSTANT_P_RTX if CSE will be run.  Moreover, we
+	     don't want to expand trees that have side effects, as we want
+	     this to be a non-intrusive function a-la sizeof.  */

Just to be pedantic, I must say that I still find this argument unsatisfying.

The ISO C standard has carefully defined sizeof so that it can be evaluated
to a constant during parsing.  One of the requirements to make this work is
that sizeof doesn't evaluate its argument.  Note that the argument isn't
evaluated because it can't be; there is no way to emit code while in the
middle of parsing an array declaration for instance.  Note that the following
are all valid uses of sizeof.  They are all valid because sizeof is defined
to evaluate to an integral constant expression.  These would not be possible
if sizeof had to evaluate its argument.

int j;
char array[sizeof(j++)];

struct foo
{
  int bar : sizeof (j++);
};

sub (i)
{
  switch (i)
    {
    case sizeof (i++):
	return 10;
    default:
      return 5;
    }
}

Now consider __builtin_constant_p.  Can it be used in an integral constant
expression?  No.  It doesn't make sense to say that __builtin_constant_p
ignores its argument just like sizeof does, because __builtin_constant_p does
not have any of the other special meanings that forces sizeof to ignore
side-effects in the argument.  Either __builtin_constant_p should evaluate
its argument for side-effects, or it should be treated as an integral
constant expression like sizeof is.  Anything in between doesn't make much
sense.

Treating __builtin_constant_p like a integral constant expression doesn't
work, though, because we can't evaluate in the parser.  With your patch,
it gets evaluated in the middle of optimization, after function inlining
has been performed.  It is clearly not an integral constant expression.
Also, note that none of these work, unlike the sizeof cases above.

char array2[__builtin_constant_p (j++)];

struct foo2
{
  int bar : __builtin_constant_p (j++);
};

sub2 (i)
{
  switch (i)
    {
    case __builtin_constant_p (i++):
      return 10;
    default:
      return 5;
    }
}

Unfortunately, while I think the current state is poor language design,
I think we are stuck with it because of existing practice.  There is so
much glibc/linux code that assumes that __builtin_constant_p does not
evaluate its argument that it is probably impossible to change it now.
I can only hope that people spend more time thinking about the design
of their language extensions in the future.

Jim



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