www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Declare a variable in an expression?

reply Chuck Esterbrook <Chuck.Esterbrook gmail.antispam.com> writes:
gcc offers a little trick where you can declare a variable in an
expression:

http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Typeof.html
"""
...a safe "maximum" macro that operates on any arithmetic type and
evaluates each of its arguments exactly once:

     #define max(a,b) \
       ({ typeof (a) _a = (a); \
           typeof (b) _b = (b); \
         _a > _b ? _a : _b; })
"""

Of course, we don't have macros for D, but I'm interested in
generating D code and having this capability would make life easier.

Is there any such capability in D?


-Chuck
Aug 25 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 25 Aug 2005 17:11:06 -0700, Chuck Esterbrook  
<Chuck.Esterbrook gmail.antispam.com> wrote:
 gcc offers a little trick where you can declare a variable in an
 expression:

 http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Typeof.html
 """
 ...a safe "maximum" macro that operates on any arithmetic type and
 evaluates each of its arguments exactly once:

      #define max(a,b) \
        ({ typeof (a) _a = (a); \
            typeof (b) _b = (b); \
          _a > _b ? _a : _b; })
 """

 Of course, we don't have macros for D, but I'm interested in
 generating D code and having this capability would make life easier.

 Is there any such capability in D?

I think "almost" is the answer. I have frequently run into the restrictions shown below.. import std.stdio; /**/ template max(Type) { Type max(Type a, Type b) { return (a > b)?a:b; }} //This makes the calls look nicer, however it's not a typeless call like the macro alias max!(byte) maxByte; alias max!(short) maxShort; alias max!(int) maxInt; alias max!(long) maxLong; alias max!(float) maxFloat; alias max!(double) maxDouble; /**/ /** template max(Type) { Type max(Type a, Type b) { return (a > b)?a:b; }} //If only we could do this, then it could be a typeless call. alias max!(byte) max; alias max!(short) max; alias max!(int) max; alias max!(long) max; alias max!(float) max; alias max!(double) max; /**/ //This would also give a typeless call. /** template maxT(Type) { Type max(Type a, Type b) { return (a > b)?a:b; }} mixin maxT!(byte); mixin maxT!(short); mixin maxT!(int); mixin maxT!(long); mixin maxT!(float); mixin maxT!(double); /**/ void main() { byte ba = 3, bb = 5; short sa = 2, sb = 9; int ia = 5, ib = 8; long la = 7, lb = 2; float fa = 3.8, fb = 9.2; double da = 2.6, db = 1.1; writefln(maxByte(ba,bb)); writefln(maxShort(sa,sb)); writefln(maxInt(ia,ib)); writefln(maxLong(la,lb)); writefln(maxFloat(fa,fb)); writefln(maxDouble(da,db)); /** writefln(max(ba,bb)); writefln(max(sa,sb)); writefln(max(ia,ib)); writefln(max(la,lb)); writefln(max(fa,fb)); writefln(max(da,db)); /**/ } Regan
Aug 25 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Fri, 26 Aug 2005 12:49:37 +1200, Regan Heath wrote:

 On Thu, 25 Aug 2005 17:11:06 -0700, Chuck Esterbrook  
 <Chuck.Esterbrook gmail.antispam.com> wrote:
 gcc offers a little trick where you can declare a variable in an
 expression:

 http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Typeof.html
 """
 ...a safe "maximum" macro that operates on any arithmetic type and
 evaluates each of its arguments exactly once:

      #define max(a,b) \
        ({ typeof (a) _a = (a); \
            typeof (b) _b = (b); \
          _a > _b ? _a : _b; })
 """

 Of course, we don't have macros for D, but I'm interested in
 generating D code and having this capability would make life easier.

 Is there any such capability in D?

I think "almost" is the answer. I have frequently run into the restrictions shown below.. import std.stdio; /**/ template max(Type) { Type max(Type a, Type b) { return (a > b)?a:b; }} //This makes the calls look nicer, however it's not a typeless call like the macro alias max!(byte) maxByte; alias max!(short) maxShort; alias max!(int) maxInt; alias max!(long) maxLong; alias max!(float) maxFloat; alias max!(double) maxDouble; /**/ /** template max(Type) { Type max(Type a, Type b) { return (a > b)?a:b; }} //If only we could do this, then it could be a typeless call. alias max!(byte) max; alias max!(short) max; alias max!(int) max; alias max!(long) max; alias max!(float) max; alias max!(double) max; /**/

But we can! The trick is to make sure the template name is not the same as the alias name. That is, you can't have 'template max ...' and 'alias ... max;' in the same scope. ------------------------- import std.stdio; template maxT(T) { T max(T a, T b) { return a > b ? a : b; } } alias maxT!(int).max max; alias maxT!(real).max max; alias maxT!(char[]).max max; void main() { writefln("%s", max(3, 6)); writefln("%s", max(3.1, 6.1)); writefln("%s", max("three", "six")); } ------------------------ -- Derek (skype: derek.j.parnell) Melbourne, Australia 26/08/2005 10:54:50 AM
Aug 25 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 26 Aug 2005 10:57:55 +1000, Derek Parnell <derek psych.ward> wrote:
 But we can! The trick is to make sure the template name is not the same  
 as the alias name. That is, you can't have 'template max ...' and 'alias  
 ...
 max;' in the same scope.

Ahh. Of course. I thought I had tried that, obviously not! :) I would still like the mixin method to work. Regan
Aug 25 2005
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Thu, 25 Aug 2005 17:11:06 -0700, Chuck Esterbrook wrote:

 gcc offers a little trick where you can declare a variable in an
 expression:

This has been requested. I think its even in the WishList poll somewhere. Basically, the enhancement would be to extend the ability to declare variables in such a way that they only have statement scope. We can already for this for 'for' and 'foreach' statements and this enhancement would extend that concept to all statements.
 http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Typeof.html
 """
 ...a safe "maximum" macro that operates on any arithmetic type and
 evaluates each of its arguments exactly once:
 
      #define max(a,b) \
        ({ typeof (a) _a = (a); \
            typeof (b) _b = (b); \
          _a > _b ? _a : _b; })
 """
 
 Of course, we don't have macros for D, but I'm interested in
 generating D code and having this capability would make life easier.

The D template system might be what you are looking for to help with most of these situations. ------------------------- import std.stdio; template maxmin(T) { T maxT(T a, T b) { return a > b ? a : b; } T minT(T a, T b) { return a < b ? a : b; } } alias maxmin!(int).maxT max; alias maxmin!(real).maxT max; alias maxmin!(char[]).maxT max; alias maxmin!(int).minT min; alias maxmin!(real).minT min; alias maxmin!(char[]).minT min; void main() { writefln("%s", max(3, 6)); writefln("%s", max(3.1, 6.1)); writefln("%s", max("three", "six")); writefln("%s", min(3, 6)); writefln("%s", min(3.1, 6.1)); writefln("%s", min("three", "six")); } -------------------- -- Derek (skype: derek.j.parnell) Melbourne, Australia 26/08/2005 10:32:19 AM
Aug 25 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Chuck Esterbrook" <Chuck.Esterbrook gmail.antispam.com> wrote in message
news:lcnsg1tas4n09ccc2pdk0h5j9ips8h2d9a 4ax.com...
 gcc offers a little trick where you can declare a variable in an
 expression:

The problem with such a syntax is the following statement: if (int a || int c) { is a in scope here? is c? } So here we have c being conditionally declared. It makes for a bit of confusing semantics.
Aug 26 2005
parent Sean Kelly <sean f4.ca> writes:
In article <denmf2$1na3$1 digitaldaemon.com>, Walter says...
"Chuck Esterbrook" <Chuck.Esterbrook gmail.antispam.com> wrote in message
news:lcnsg1tas4n09ccc2pdk0h5j9ips8h2d9a 4ax.com...
 gcc offers a little trick where you can declare a variable in an
 expression:

The problem with such a syntax is the following statement: if (int a || int c) { is a in scope here? is c? } So here we have c being conditionally declared. It makes for a bit of confusing semantics.

The spec isn't particularly clear on this point, but declaring a variable in a selection statement is legal in C++ (6.4.3): "A name introduced by a declaration in a condition (either introduced by the type-specifier-seq or the declarator of the condition) is in scope from its point of declaration until the end of the substatements controlled by the condition." Oddly, it means this is legal: # void fn( int v ) { # if( int x = v ) # cout << "yes: " << x; # else # cout << "no: " << x; # } Sean
Aug 26 2005