www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - "non-constant expression" error

reply Carotinho <carotinobg yahoo.it> writes:
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
Dec 04 2004
next sibling parent Carotinho <carotinobg yahoo.it> writes:
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:)
Dec 04 2004
prev sibling parent reply Sebastian Beschke <s.beschke gmx.de> writes:
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
Dec 04 2004
next sibling parent reply Carotinho <carotinobg yahoo.it> writes:
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
Dec 04 2004
parent reply Chris Sauls <Chris_member pathlink.com> writes:
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
Dec 04 2004
next sibling parent "Simon Buchan" <currently no.where> writes:
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"
Dec 05 2004
prev sibling parent Carotinho <carotinobg yahoo.it> writes:
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
Dec 06 2004
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
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...
Dec 05 2004
parent reply Carotinho <carotinobg yahoo.it> writes:
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
Dec 07 2004
parent =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
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
Dec 07 2004