Works in Clang 2.9 and Clang 3.0 Succeeds in g++ FWIW. $ gcc gcc_bug.c gcc_bug.c:5: error: initializer element is not constant
Created attachment 27224 [details] Demo of problem
The bug reporting guidelines ask for source code, not a URL. Here's the code from the URL #include <stdio.h> const int SDL_HAT_UP = 0x01; const int SDL_HAT_RIGHT = 0x02; const int SDL_HAT_RIGHTUP = (SDL_HAT_RIGHT | SDL_HAT_UP); int main(int argc, char **argv) { printf("%x\n",SDL_HAT_RIGHTUP); return 0; } I think GCC is correct, the code is valid C++ but not valid C. In C the initializer for a global variable must be a constant expression ("All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.") and (SDL_HAT_RIGHT | SDL_HAT_UP) is not a constant expression. http://c-faq.com/ansi/constasconst.html I believe Clang is allowed to accept the code because the C standard also says implementations may accept other forms of constant expression.
Hey. I attached it as well. I didn't just provide a URL. Anyway, I take it this is a "Won't Fix" ? I guess it isn't the end of the world since we are targetting clang for llvm output anyway. Although gcc would be nice-to-have. I don't think he's big on making specialcase #defines in this converter.
Just use an enum.
(In reply to comment #3) > Anyway, I take it this is a "Won't Fix" ? Not sure why. If Clang is allowed by the C standard, then surely GCC is allowed as well. If the C++ FE has code to enable this, probably it can be reused in the C FE. GCC could accept it with a -Wpedantic warning. In any case, like everything, it boils down to having someone make it happen, that is, providing a patch. I don't think any existing GCC developer will tackle this in the near future, otherwise it would have been done already. But let's wait for Joseph opinion to confirm this.
Oh, cool. Probably going to replace w/ an enum, which does seem to work. But it does make 0 sense to me that const int is forbidden, but enum is allowed... http://publications.gbdirect.co.uk/c_book/chapter6/enums.html Can rewrite both const int and enum, so I don't really see why enum is permitted but const int isn't, they both offer about the same amount of safety. I mean, might as well just force #define only. (please don't!)
>But it does make 0 sense to me that const int is forbidden, but enum is allowed... Why variables are not part of C's constant integer expressions. enum values are not variables.
In response to comment #7, I was referring to this portion of the linked document. ------ Not that you are likely to care, but the Standard states that enumeration types are of a type that is compatible with an implementation-defined one of the integral types. So what? For interest's sake here is an illustration: enum ee{a,b,c}e_var, *ep; The names a, b, and c all behave as if they were int constants when you use them; ------ So. you can rewrite enum values just as easily as you can a const int by taking a pointer to it. And that site claims it behaves like a const int. So, yeah, gotta say clang's behaviour seems more rational here. Oh well. unc0rr might switch to enum in the interest of getting it working. The conversion code is not quite as tidy, but no matter. I'll let you guys hash it out. At leas clang works for now.
enum constants are not objects, they don't have an address.
(In reply to comment #3) > Hey. I attached it as well. I didn't just provide a URL. Yeah, sorry, I wrote my comment before you attached it. (In reply to comment #6) > Can rewrite both const int and enum, so I don't really see why enum is > permitted but const int isn't, they both offer > about the same amount of safety. http://c-faq.com/ansi/constasconst.html Take it up with the C committee, not GCC. (In reply to comment #8) > Not that you are likely to care, but the Standard states that enumeration types > are of a type that is compatible with an implementation-defined one of the > integral types. Enumeration TYPES are compatible with integral TYPES. But enumerators are constant, const-qualified variables are not constants. > So. you can rewrite enum values just as easily as you can a const int by taking > a pointer to it. And that site claims it behaves like a const int. The site's wrong.
Yeah, I get the difference now. Ok. Fair. So, I guess clang is just taking the values of the const ints at the time the assignment occurs (0x01 and 0x02) and assigning 0x03. If RIGHT or UP were changed, RIGHTUP would not change. Ok, what gcc is doing *does* make sense I 'spose :)
There is no requirement to accept this static initializer, but the code does try to be lax about constants in initializers (there is no requirement to reject it either) and fold them with c_fully_fold (see c-typeck.c:digest_init). So it may make sense to look at why this laxity isn't causing this code to be accepted.
(In reply to comment #12) > There is no requirement to accept this static initializer, but the code > does try to be lax about constants in initializers (there is no > requirement to reject it either) and fold them with c_fully_fold (see > c-typeck.c:digest_init). So it may make sense to look at why this laxity > isn't causing this code to be accepted. So confirmed. bugs@m8y.org, I would recommend that if you are interested in this, take a more active role. First, by finding out where and why the C FE does not accept this code. Then posting the results of your investigation here.
Heh. Thanks, but our current target is clang->llvm, I was just surprised that gcc did not accept it. The codebase being converted by unc0rr's haskell-based tokeniser is pascal actually. const SDL_HAT_UP = $01; SDL_HAT_RIGHT = $02; SDL_HAT_RIGHTUP = SDL_HAT_RIGHT or SDL_HAT_UP; Sooo, if you guys make it work in GCC, great, could be useful in the future, maybe for faster game builds on the desktop. But not really a big priority. Besides, unc0rr can probably change that to: enum _consts { SDL_HAT_UP = 0x01, SDL_HAT_RIGHT = 0x02, SDL_HAT_RIGHTUP = (SDL_HAT_RIGHT | SDL_HAT_UP) }; To satisfy gcc's more delicate sensibilities. :-p Thanks for looking into it though, and I'll definitely watch the bug.
*** Bug 53530 has been marked as a duplicate of this bug. ***
Fixed for GCC 8 by r8-5025