Re: Now that SCM type is a union...
-[ Sat, Aug 13, 2011 at 01:26:03AM -0400, Ken Raeburn ] > ("Is for some reason invalid" is not very descriptive; please include > specific compiler messages.) Sorry ; the specific error message was, you guesssed it right: "initializer element is not constant". > That syntax -- the parenthesized type followed by a list of initializers in > braces -- is called a "compound literal" (technically not a cast expression) > and was added in C99. The value of a compound literal is an anonymous object > with a value given by the initializer elements. (It's an lvalue, and can > even have its address taken.) That means it's not a "constant expression" > and cannot be used for static initialization, under C99 rules. Yes thank you for clarifying this. In this context of initializing a global variable my brain failed to recognize a compound literal. It all make sense now, both why it's used and why gcc is complaining. Now it seams indeed wrong to use an anonymous lvalue as an initializer. > The GCC documentation says that a GCC extension permits such initialization. Even if it was the case, would it be a good idea for header files that are supposed to be included in user programs to rely on a gcc extension ? > From that I'd kind of expect it to work in gnu89 or gnu99 modes, and maybe > not c89, but apparently that's not how they did it... It actualy works with gnu89 or c89, but neither gnu99 nor c99 : ---[ foobar.c ]--- struct foo { int a; }; struct foo bar = (struct foo){ 1 }; ---[ /foobar.c ]--- make foobar.o CFLAGS="-std=gnu99" foobar.c:2:26: error: initializer element is not constant same goes for c99 ; while: make foobar.o CFLAGS="-std=c89" works. > Have an initialization function which stuffs SCM_UNSPECIFIED into a bunch of > uninitialized SCM variables before making them accessible from other code? > Yeah, it's kind of unfortunate. Especially unfortunate if one do not want to rely on gcc specific constructor to initialize it automagically ; and it makes programs that were working with former versions of guile fails to compile which is not so nice. > Maybe we need a separate set of macros for static initialization using > SCM_UNDEFINED, SCM_BOOL_F, and friends? I'd like it. Or maybe instead of checking for a PREHISTORIC_COMPILER the header files may check for actual compiler settings (ie. if C99 conformance is required then don't use the union) ; if the underlying encoding of the alternative is the same, of course. > It looks like Guile is compiled in the default (gnu89?) mode, not C99. It > has a few places where static variables are initialized using SCM_BOOL_F, > which will have the same problem. Yes, whenever c99 becomes the default (it's only 12 years old now).
Re: Now that SCM type is a union...
On Sat 13 Aug 2011 07:26, Ken Raeburn writes: > That syntax -- the parenthesized type followed by a list of initializers > in braces -- is called a "compound literal" (technically not a cast > expression) and was added in C99. The value of a compound literal is an > anonymous object with a value given by the initializer elements. (It's > an lvalue, and can even have its address taken.) That means it's not a > "constant expression" and cannot be used for static initialization, > under C99 rules. I only have a draft copy of C99, from 7 September 2007, but it does permit constant expressions to appear outside function bodies. How could that happen except for in initializers? I do see the language in the GCC docs though; it's confusing. I was under the impression that they would be constant expressions, but perhaps I was mistaken. I will take a look at this issue soonish, but your help (and Cedric's) in debugging it is most appreciated :) I would love to keep the union as the "normal" SCM definition, but that might not be possible. Regards, Andy -- http://wingolog.org/
Re: Now that SCM type is a union...
On Aug 13, 2011, at 08:23, Andy Wingo wrote: > I only have a draft copy of C99, from 7 September 2007, but it does > permit constant expressions to appear outside function bodies. How > could that happen except for in initializers? I do see the language in > the GCC docs though; it's confusing. I was under the impression that > they would be constant expressions, but perhaps I was mistaken. It is confusing. There's an example in the final spec which I think indicates what's happening: int *p = (int []){2, 4}; // definition at file scope, outside any fn The compound literal produces an anonymous object (with static storage duration, in this case) of type "int[2]"; in this context, its initialization elements have to be constants. Through the standard conversion of array to pointer-to-element, the value of this expression becomes an "int *" which is used to initialize p (allowed because the object has static storage duration and thus its address is a constant). When array/pointer conversions aren't involved, you might assume you could just initialize a variable statically, but since the compound literal creates an object, an lvalue, it's more like saying: static int anon = 3; // "anonymous" obj with constant initializer int x = anon; // not allowed in C99 You could make "anon" const, but it wouldn't change anything, under C99 rules. Note, too, that the unnamed object created doesn't need to be "const" -- changing p[0] above is perfectly valid. Though if you use const in the type, then the compiler is permitted to combine identical values and store only one copy. Also: * We should expect some Guile applications to be in C++. What versions of the C++ spec should Guile support? * Shouldn't there be testing to catch this? (C89 mode, C99 mode, different C++ specs, enabling various compiler warnings -- for whatever compiler is in use -- and make them fatal, any interesting ways one might want to use libguile in an application that might stress compatibility issues.) I mean automated testing, not just Cedric. :-) > I will take a look at this issue soonish, but your help (and Cedric's) > in debugging it is most appreciated :) I would love to keep the union > as the "normal" SCM definition, but that might not be possible. Regardless of the validity, there are popular compilers out there now which do not support this, when used in modes people may need or want to use. The installed headers need to adhere to higher standards in terms of portability problems and warnings than the library source, where we can dictate some of the compiler options. Ken
Re: Compatibility V1.8 and 2.0 - deprecated (debug-enable 'debug)
() Ian Hulin () Wed, 10 Aug 2011 19:50:23 +0100 Thanks for the info, it would be useful but we need to things at run-time. We've got stuff in an initialization scheme script which is called from the Lilypond code image and this historically has done the (debug-enable 'debug) call. Another idea is to move these small pieces into separate files and conditionally load them... I want to be able to code it for backwards-compatibility for Guile V2 and Guile V1.8, and also not cause any deprecation warnings when running with Guile V2. E.g. ;;; Boolean thunk - are we integrating Guile V2.0 or higher with Lily? (define-public (guile-v2) (string>? (version) "1.9.10")) ... based on ‘guile-v2’ (for example). This might be enough to keep the deprecation warnings from appearing. I don't know for sure, however.