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

Re: gcc: why is "abcdef"[3] not a constant (error: initializer element is not constant)


On 08/05/15 17:19, Martin wrote:
On 05/08/2015 08:34 AM, m-h-l wrote:
Funny thing is that g++, ArmC and ICC do not have a problem with "abcdef"[3]
as an initializer.
So I wonder what shall be the sense to forbid this in gcc.
This way I cannot use gcc to calculate e.g. CRCs or Hashs over real constant things at build time without extra tools, even not in such a clear case as
here. With the other compilers its no problem.

It is true that the C standard requires a constant expression in this
context and that the bracket expression is not such an expression, so
the program isn't strictly conforming.

However, the C standard leaves room for implementations to provide
extensions as long as they don't change the behavior of strictly
conforming programs. Unless such a program can be constructed that
would detect such an extension, providing it wouldn't make
an implementation wrong (non-conforming). GCC has a rich set of
extensions so there is a precedent for such a request if one should
be made. I would encourage you to open a Bugzilla and include your
arguments in it.

Martin
+1

I'm afraid Andrew email was misguided, appearing as rude. gcc has many extensions, and there's no reason it couldn't add this one, which I agree would be useful.

I think the difference you mention is that the code is being rejected before doing constant folding (or simply, not accepting a string literal). It is funny because I had thought I had successfully done something like that in the past (maybe an old version of gcc allowed it?) nut browsing my code, what I found was quite the opposite, a case where I ending up passing to a macro several character constants instead of a constant string precisely to work around this problem.


As for g++ accepting that syntax, I would't take for granted that it is doing it at build time. I think the compiler allows it just as it would accept:
typedef struct
{
    const char  oneChar;
    int ptr2;
} xxx_t;
static xxx_t ms =  { "12345"[3], *rand()* };

So I think it is accepting it because it intends to later run the code for its initialization (it should later notice it is actually constant and be able to optimize it).

If you try that construct a switch, where the compiler absolutely requires it to be available at build time, g++ also fails to compile it:
  switch (argc) {
        case "12345"[3]:
            break;
        default:
            return 1;
    }

produces
error: an array reference cannot appear in a constant-expression


Best regards


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