www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Failed static if still compiles?

reply Kyle Furlong <kylefurlong gmail.com> writes:
With the code,

struct Vector(T, int Dim = 4)
{
...	
	Vector ImaginaryPart()
	{
		static if(!isRealType!(T))
		{
			Vector imaginarypart;
			for(int i = 0; i < Dim; i++)
			{
			imaginarypart[i] = cast(T)(storage[i].im);
			}
			return imaginarypart;
		}
		else
		{
		throw new VelocityException("velocity.math.Vector: 					Non-complex 
types do not have a imaginary 					part.");	
		}
	}
...
}

one finds that the code,

Vector!(int, 3) vec;

causes the compiler to choke with the message:

C:\dmd\bin\build.exe Vector.d -clean -O -inline -release
\d\import\velocity\math\Vector.d(103): no property 'im' for type 'int'
... (more errors follow)

This was extremely confusing to me until I read in the spec:

A StaticIfConditional condition differs from an IfStatement in the 
following ways:

    1. It can be used to conditionally compile declarations, not just 	 
statements.
    2. It does not introduce a new scope even if { } are used for 
conditionally compiled statements.
    3. For unsatisfied conditions, the conditionally compiled code need 
only be syntactically correct. It does not have to be semantically correct.
    4. It must be evaluatable at compile time.

IMHO, it is ridiculous for the main mechanism of conditional compilation 
to evaluate the code that the author is trying to AVOID with the static if.
Jan 30 2006
parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Kyle Furlong wrote:
 With the code,
 
 struct Vector(T, int Dim = 4)
 {
 ...   
     Vector ImaginaryPart()
     {
         static if(!isRealType!(T))
         {
             Vector imaginarypart;
             for(int i = 0; i < Dim; i++)
             {
             imaginarypart[i] = cast(T)(storage[i].im);
             }
             return imaginarypart;
         }
         else
         {
         throw new 
 VelocityException("velocity.math.Vector:                     Non-complex 
 types do not have a imaginary                     part.");   
         }
     }
 ...
 }
 
 one finds that the code,
 
 Vector!(int, 3) vec;
 
 causes the compiler to choke with the message:
 
 C:\dmd\bin\build.exe Vector.d -clean -O -inline -release
 \d\import\velocity\math\Vector.d(103): no property 'im' for type 'int'
 ... (more errors follow)

How is isRealType defined? Try to replace !isRealType!(T) with: (is(T == creal) || is(T == cdouble) || is(T == cfloat)) and the code (should) compile.
 This was extremely confusing to me until I read in the spec:
 
 A StaticIfConditional condition differs from an IfStatement in the 
 following ways:
 
    1. It can be used to conditionally compile declarations, not 
 just      statements.
    2. It does not introduce a new scope even if { } are used for 
 conditionally compiled statements.
    3. For unsatisfied conditions, the conditionally compiled code need 
 only be syntactically correct. It does not have to be semantically correct.
    4. It must be evaluatable at compile time.
 
 IMHO, it is ridiculous for the main mechanism of conditional compilation 
 to evaluate the code that the author is trying to AVOID with the static if.

But storage[i].im is syntactically correct... Even if the type of storage[i] is int. /Oskar
Jan 31 2006
parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Oskar Linde wrote:
 Kyle Furlong wrote:
 With the code,

 struct Vector(T, int Dim = 4)
 {
 ...       Vector ImaginaryPart()
     {
         static if(!isRealType!(T))
         {
             Vector imaginarypart;
             for(int i = 0; i < Dim; i++)
             {
             imaginarypart[i] = cast(T)(storage[i].im);
             }
             return imaginarypart;
         }
         else
         {
         throw new 
 VelocityException("velocity.math.Vector:                     
 Non-complex types do not have a imaginary                     
 part.");           }
     }
 ...
 }

 one finds that the code,

 Vector!(int, 3) vec;

 causes the compiler to choke with the message:

 C:\dmd\bin\build.exe Vector.d -clean -O -inline -release
 \d\import\velocity\math\Vector.d(103): no property 'im' for type 'int'
 ... (more errors follow)

How is isRealType defined? Try to replace !isRealType!(T) with: (is(T == creal) || is(T == cdouble) || is(T == cfloat)) and the code (should) compile.

The whole point is that this is supposed to happen at compile time, not run time. Thus the static if with template instantiation.
 This was extremely confusing to me until I read in the spec:

 A StaticIfConditional condition differs from an IfStatement in the 
 following ways:

    1. It can be used to conditionally compile declarations, not 
 just      statements.
    2. It does not introduce a new scope even if { } are used for 
 conditionally compiled statements.
    3. For unsatisfied conditions, the conditionally compiled code need 
 only be syntactically correct. It does not have to be semantically 
 correct.
    4. It must be evaluatable at compile time.

 IMHO, it is ridiculous for the main mechanism of conditional 
 compilation to evaluate the code that the author is trying to AVOID 
 with the static if.

But storage[i].im is syntactically correct... Even if the type of storage[i] is int. /Oskar

Apparently dmd disagrees with you that it is correct. But regardless of whether it is correct or not, my point was that, IMHO, it shouldn't matter. Whichever branch is not taken from the static if should not be parsed. Correct me if this usage is not good code practice, with examples of better practice if possible.
Jan 31 2006
parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Kyle Furlong wrote:
 Oskar Linde wrote:
 Kyle Furlong wrote:
 With the code,

 struct Vector(T, int Dim = 4)
 {
 ...       Vector ImaginaryPart()
     {
         static if(!isRealType!(T))
         {
             Vector imaginarypart;
             for(int i = 0; i < Dim; i++)
             {
             imaginarypart[i] = cast(T)(storage[i].im);
             }
             return imaginarypart;
         }
         else
         {
         throw new 
 VelocityException("velocity.math.Vector:                     
 Non-complex types do not have a imaginary                     
 part.");           }
     }
 ...
 }

 one finds that the code,

 Vector!(int, 3) vec;

 causes the compiler to choke with the message:

 C:\dmd\bin\build.exe Vector.d -clean -O -inline -release
 \d\import\velocity\math\Vector.d(103): no property 'im' for type 'int'
 ... (more errors follow)

How is isRealType defined? Try to replace !isRealType!(T) with: (is(T == creal) || is(T == cdouble) || is(T == cfloat)) and the code (should) compile.

The whole point is that this is supposed to happen at compile time, not run time. Thus the static if with template instantiation.

But the above is a compile time construct. static if (is(T == creal) || is(T == cdouble) || is(T == cfloat)) { ... }
 
 This was extremely confusing to me until I read in the spec:

 A StaticIfConditional condition differs from an IfStatement in the 
 following ways:

    1. It can be used to conditionally compile declarations, not 
 just      statements.
    2. It does not introduce a new scope even if { } are used for 
 conditionally compiled statements.
    3. For unsatisfied conditions, the conditionally compiled code 
 need only be syntactically correct. It does not have to be 
 semantically correct.
    4. It must be evaluatable at compile time.

 IMHO, it is ridiculous for the main mechanism of conditional 
 compilation to evaluate the code that the author is trying to AVOID 
 with the static if.

But storage[i].im is syntactically correct... Even if the type of storage[i] is int. /Oskar

Apparently dmd disagrees with you that it is correct. But regardless of whether it is correct or not, my point was that, IMHO, it shouldn't matter. Whichever branch is not taken from the static if should not be parsed. Correct me if this usage is not good code practice, with examples of better practice if possible.

The parsing is not the problem in this case. 3) above says that the code need not be semantically correct. That seems to me to be all you need. Type resolution is done in the semantic phase. If the compiler allowed non syntactically correct code within a static if construct, the entire compilation process would not be separable into syntactic / semantic phases. (A static if condition must be evaluated during the semantic phase.) /Oskar
Jan 31 2006