foreach range construction bug?!!?!?!?

Phil Lavoie maidenphil at hotmail.com
Sun Jan 6 10:59:33 PST 2013


Hi all,

I am very close to posting a bug report, however I would like 
some insights first. See the code below:

module newstructerror;

alias int GLint;
alias uint GLenum;

enum {
   GL_EXTENSIONS
}

/* Errors */
enum {
  GL_NO_ERROR                             = 0x0,
  GL_INVALID_VALUE                        = 0x0501,
  GL_INVALID_ENUM                         = 0x0500,
  GL_INVALID_OPERATION                    = 0x0502,
  GL_STACK_OVERFLOW                       = 0x0503,
  GL_STACK_UNDERFLOW                      = 0x0504,
  GL_OUT_OF_MEMORY                        = 0x0505,
}

version( Defined ) {
   extern( C ) nothrow {
     void glGetIntegerv( GLenum p, GLint * v ) {
       //Do nothing;
     }

     GLenum glGetError() {
       return GL_INVALID_OPERATION;
     }
   }
} else {
   pragma( lib, "opengl32.lib" );
   extern( C ) nothrow {
     void glGetIntegerv( GLenum p, GLint * v );
     GLenum glGetError();
   }
}

import std.stdio;

void main( string[] args ) {
   GLint noExt = -1;
   glGetIntegerv( GL_EXTENSIONS, &noExt );
   writeln( "Number of extensions: ", noExt );

   version( Working ) {
     //Works with both.
     auto errors = GLErrors();
     foreach( GLenum err; errors ) {
       writeln( glError( err ) );
     }
   } else {
     //Crashes in non defined version.
     foreach( GLenum err; GLErrors() ) {
       writeln( glError( err ) );
     }
   }

}

string glError( GLenum errCode ) {
   switch( errCode ) {
   case GL_NO_ERROR:
     return "no error";
   case GL_INVALID_VALUE:
     return "invalid value";
   case GL_INVALID_ENUM:
     return "invalid enum";
   case GL_INVALID_OPERATION:
     return "invalid operation";
   case GL_STACK_OVERFLOW:
     return "stack overflow";
   case GL_STACK_UNDERFLOW:
     return "stack underflow";
   case GL_OUT_OF_MEMORY:
     return "out of memory";
   default:
     return "unknown error";
   }
}

struct GLErrors {
   private GLenum _current;
public:
   @property bool empty() {
     _current = glGetError();
     return ( _current == GL_NO_ERROR );
   }
   @property GLenum front() {
     return _current;
   }
   void popFront() { ; }
}

Now here is what is really troubling me, the non defined version 
(using the import library) crashes when the range constructor is 
called inside the foreach statement, which is weird by itself. In 
addition, in DOES NOT crash when the functions are artifically 
defined. Anyone seen that before? Or maybe I am doing something 
wrong?

This is the program output when you don't define any versions:
Number of extensions: -1
object.Error: Access Violation
----------------
0x0040DAD8
0x0040D963
0x7799B459 in LdrRemoveLoadAsDataTable
0x7799B42B in LdrRemoveLoadAsDataTable
0x77950133 in KiUserExceptionDispatcher
0x00403A20
0x00403A56
0x00403659
0x00402830
0x751A33AA in BaseThreadInitThunk
0x77979EF2 in RtlInitializeExceptionChain
0x77979EC5 in RtlInitializeExceptionChain
----------------

Defining Working or Defined will produce an infinite loop (or 
maybe not).

Thanks for your time!
Phil



More information about the Digitalmars-d-learn mailing list