Thread overview
"non-constant expression" error
Dec 04, 2004
Carotinho
Dec 04, 2004
Carotinho
Dec 04, 2004
Sebastian Beschke
Dec 04, 2004
Carotinho
Re:
Dec 04, 2004
Chris Sauls
Dec 05, 2004
Simon Buchan
Dec 06, 2004
Carotinho
Dec 07, 2004
Carotinho
December 04, 2004
hi!

I've defined

int AL_ID(int a, int b, int c, int d) { return (((a)<<24) | ((b)<<16) |
((c)<<8) | (d)); }

and later

int SYSTEM_NONE        = AL_ID('N','O','N','E');

and dmd says me that

allegro.d(135): non-constant expression AL_ID(cast(int)(78),cast(int
(79),cast(int)(78),cast(int)(69))

But if I define

int SYSTEM_NONE = ((('N')<<24) | (('O')<<16) | (('c')<<8) | ('d'));

then everything is all right.

I would like to know the meaning of the "non-constant expression" error, and why it applies here.

thanks a lot:)

Carotinho
December 04, 2004
Carotinho wrote:

> int SYSTEM_NONE = ((('N')<<24) | (('O')<<16) | (('c')<<8) | ('d'));

Sorry that's I typo. it was obviously

int SYSTEM_NONE = ((('N')<<24) | (('O')<<16) | (('N')<<8) | ('E'));

Besides, that definition of AL_ID and SYSTEM_NONE is working well in another file, but not in the module I'm working out.

Thanks again:)

December 04, 2004
Hi,

Carotinho wrote:
> hi!
> 
> I've defined
> 
> int AL_ID(int a, int b, int c, int d) { return (((a)<<24) | ((b)<<16) |
> ((c)<<8) | (d)); }
> 
> and later
> 
> int SYSTEM_NONE        = AL_ID('N','O','N','E');
> 
> and dmd says me that 
> 
> allegro.d(135): non-constant expression AL_ID(cast(int)(78),cast(int
> (79),cast(int)(78),cast(int)(69))

The function AL_ID() needs to be called in order to evaluate the expression AL_ID('N','O','N','E'), which can't be done at compile time. Thus, you can't use it to initialize globals.

> 
> But if I define 
> 
> int SYSTEM_NONE = ((('N')<<24) | (('O')<<16) | (('c')<<8) | ('d'));
> 
> then everything is all right.

This expression is evaluated at compile time.

HTH
-Sebastian
December 04, 2004
Hi!

Sebastian Beschke wrote:

> The function AL_ID() needs to be called in order to evaluate the
> expression AL_ID('N','O','N','E'), which can't be done at compile time.
> Thus, you can't use it to initialize globals.

Aaah, now I understand... :)
Thanks a lot!:)

Byez!

Carotinho
December 04, 2004
Your question is answered, but something you might consider..  If you really, really want to have that set immediately upon execution, consider using a module constructor.  Aka, something like:

#
# int AL_ID(int a, int b, int c, int d) {
#   return (((a)<<24) | ((b)<<16) | ((c)<<8) | (d));
# }
#
# int SYSTEM_NONE;
#
# static this() {
#   SYSTEM_NONE = AL_ID('N', 'O', 'N', 'E');
# }
#

These are evaluated previous to main() being called, so the effect is much the same as your original intent.

-- Chris Sauls


December 05, 2004
On Sat, 4 Dec 2004 20:46:27 +0000 (UTC), Chris Sauls <Chris_member@pathlink.com> wrote:

> Your question is answered, but something you might consider..  If you really,
> really want to have that set immediately upon execution, consider using a module
> constructor.  Aka, something like:
>
> #
> # int AL_ID(int a, int b, int c, int d) {
> #   return (((a)<<24) | ((b)<<16) | ((c)<<8) | (d));
> # }
> #
> # int SYSTEM_NONE;
> #
> # static this() {
> #   SYSTEM_NONE = AL_ID('N', 'O', 'N', 'E');
> # }
> #
>
> These are evaluated previous to main() being called, so the effect is much the
> same as your original intent.
>
> -- Chris Sauls
>
>

With the small side effect that you get a VERY small increase
in startup time. (As in, a millionth of that needed to init the rest
of D's stuff)
If you happen to be doing 2 million of these types of things, you can
use templates to evaluate at compile time, but it can get pretty
verbose.

-- 
"Unhappy Microsoft customers have a funny way of becoming Linux,
Salesforce.com and Oracle customers." - www.microsoft-watch.com:
"The Year in Review: Microsoft Opens Up"
December 05, 2004
Sebastian Beschke wrote:

>> I've defined
>>
>> int AL_ID(int a, int b, int c, int d) { return (((a)<<24) | ((b)<<16) |
>> ((c)<<8) | (d)); }
>>
>> and later
>>
>> int SYSTEM_NONE        = AL_ID('N','O','N','E');
>>
>> and dmd says me that
>> allegro.d(135): non-constant expression AL_ID(cast(int)(78),cast(int
>> (79),cast(int)(78),cast(int)(69))
> 
> The function AL_ID() needs to be called in order to evaluate the expression AL_ID('N','O','N','E'), which can't be done at compile time. Thus, you can't use it to initialize globals.

This issue occurs a lot when you try and translate C code,
that used to used the preprocessor (i.e. with a #define)

As has been said, D has no preprocessor so you need to either
expand it yourself (i.e. cut and paste) or make it into code...


The only problem with making it into code, besides the trivial
run-time overhead, is that you get objects for your D wrapper.

So you don't just get a bunch of .d module files wrapping the .h,
but you also get a library (.a/.lib) with the wrapper code needed...


SDL is a good (read: bad) example of using such pre-processor
tricks in the library headers, which makes wrapping it "fun".

--anders


PS. You can use a C / C++ compiler (or even "cpp" directly)
    to expand macros in the .h headers, before porting to D...
December 06, 2004
Chris Sauls wrote:

> Your question is answered, but something you might consider..  If you
> really, really want to have that set immediately upon execution, consider
> using a module
> constructor.  Aka, something like:
> 
> #
> # int AL_ID(int a, int b, int c, int d) {
> #   return (((a)<<24) | ((b)<<16) | ((c)<<8) | (d));
> # }
> #
> # int SYSTEM_NONE;
> #
> # static this() {
> #   SYSTEM_NONE = AL_ID('N', 'O', 'N', 'E');
> # }
> #
> 
> These are evaluated previous to main() being called, so the effect is much the same as your original intent.
> 
> -- Chris Sauls

Hi!
Now I've figured out the meaning of static constuctor, but I managed to
obtain the values and just copying them in the module, which is much less
elegant but equally functional!
Thanks again:)

Carotinho

December 07, 2004
Hi!

Anders F Björklund wrote:

> This issue occurs a lot when you try and translate C code, that used to used the preprocessor (i.e. with a #define)

Actually it is what I'm doing :)

> SDL is a good (read: bad) example of using such pre-processor tricks in the library headers, which makes wrapping it "fun".

... I'm indeed wrapping Allegro which is another gaming library, with that sort of pre-processor fun :)

> PS. You can use a C / C++ compiler (or even "cpp" directly)
>      to expand macros in the .h headers, before porting to D...

it's gcc -c switch, am I right?

byez!

Carotinho
December 07, 2004
Carotinho wrote:

>>PS. You can use a C / C++ compiler (or even "cpp" directly)
>>     to expand macros in the .h headers, before porting to D...
> 
> it's gcc -c switch, am I right?

You might find "gcc --help" to be useful: (or man or info, but)

>  -c         Compile and assemble, but do not link

>  -E         Preprocess only; do not compile, assemble or link

The flag you want is -E, and possibly some -D defines as well ?

--anders