digitalmars.D - Defining a version after it's tested for
- Robert Clipsham <robert octarineparrot.com> May 21 2009
- "Tim Matthews" <tim.matthews7 gmail.com> May 21 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> May 21 2009
- Robert Clipsham <robert octarineparrot.com> May 21 2009
- Robert Clipsham <robert octarineparrot.com> May 22 2009
- Robert Clipsham <robert octarineparrot.com> May 22 2009
- "Tim Matthews" <tim.matthews7 gmail.com> May 21 2009
- Don <nospam nospam.com> May 22 2009
- "Tim Matthews" <tim.matthews7 gmail.com> May 22 2009
I recently came across this:
version( BackendFoo ) {}
else version( BackendBar ) {}
else version( BackendCar ) {}
else
{
pragma( msg, "Warning: backend version undefined" );
pragma( msg, "Attempting to guess backend" );
version( Windows )
{
version = BackendFoo;
pragma( msg, "Selected the Foo backend." );
}
else version(...)
{ /* You get the idea */ }
}
However, when trying to compile I get the following error:
Error: version BackendFoo defined after use
What is the reasoning behind this? It could be extremely useful to have
this functionality. The only reason I can think of for doing this is
that this code could be evaluated after modules that depend on the
version being defined, causing it not to work. Surely there would be a
way around that?
If it's not possible to fix this, what way would you recommend I get
around this? The only idea I've come up with so far is to do:
else
{
static assert( false, "Please compile with
-version=Backend(Foo|Bar|Bar)" );
}
Which is less than optimal.
May 21 2009
------------BlKq31CYPBdTAKLNvjfMO1 Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15 Content-Transfer-Encoding: 7bit On Fri, 22 May 2009 02:45:24 +1200, Robert Clipsham <robert octarineparrot.com> wrote:If it's not possible to fix this, what way would you recommend I get around this?
I think versions are powerfull enough so I created a wrapper around which makes best use of static asserts (attached) I think the reason behind this is to discourage version usage. ------------BlKq31CYPBdTAKLNvjfMO1 Content-Disposition: attachment; filename=Vers.d Content-Type: application/octet-stream; name=Vers.d Content-Transfer-Encoding: Base64 DQptb2R1bGUgVmVyczsNCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioNCg0KICAgICAgICBBIHNpbXBsZSB0ZW1wbGF0ZSB3cmFwcGVyIGFyb3VuZCBE IHZlcnNpb25zLiBFeGFtcGxlIHVzYWdlOg0KDQogICAgICAgIHN0YXRpYyBhc3Nl cnQodmVycyEoTGl0dGxlRW5kaWFuKSB8fCB2ZXJzIShCaWdFbmRpYW4pLA0KICAg ICAgICAiWW91IGFyZSBhIHdlaXJkIGVuZGlhbiIpOw0KDQoqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqLw0KDQoNCnRlbXBsYXRlIHZlcnMoY2hhcltdIFYp DQp7DQogICAgICBtaXhpbigidmVyc2lvbigiIH4gViB+ICIpDQogICAgICB7DQog ICAgICAgICAgICBjb25zdCBib29sIHZlcnMgPSB0cnVlOw0KICAgICAgfQ0KICAg ICAgZWxzZQ0KICAgICAgew0KICAgICAgICAgICAgY29uc3QgYm9vbCB2ZXJzID0g ZmFsc2U7DQogICAgICB9Iik7DQp9DQoNCmNvbnN0IERpZ2l0YWxNYXJzID0gIkRp Z2l0YWxNYXJzIjsNCmNvbnN0IFg4NiA9ICJYODYiOw0KY29uc3QgWDg2XzY0ID0g Ilg4Nl82NCI7DQpjb25zdCBXaW5kb3dzID0gIldpbmRvd3MiOw0KY29uc3QgV2lu MzIgPSAiV2luMzIiOw0KY29uc3QgV2luNjQgPSAiV2luNjQiOw0KY29uc3QgbGlu dXggPSAibGludXgiOw0KY29uc3QgTGl0dGxlRW5kaWFuID0gIkxpdHRsZUVuZGlh biI7DQpjb25zdCBCaWdFbmRpYW4gPSAiQmlnRW5kaWFuIjsNCmNvbnN0IERfQ292 ZXJhZ2UgPSAiRF9Db3ZlcmFnZSI7DQpjb25zdCBEX0Rkb2MgPSAiRF9EZG9jIjsN CmNvbnN0IERfSW5saW5lQXNtX1g4NiA9ICJEX0lubGluZUFzbV9YODYiOw0KY29u c3QgRF9JbmxpbmVBc21fWDg2XzY0ID0gIkRfSW5saW5lQXNtX1g4Nl82NCI7DQpj b25zdCBEX0xQNjQgPSAiRF9MUDY0IjsNCmNvbnN0IERfUElDID0gIkRfUElDIjsN CmNvbnN0IG5vbmUgPSAibm9uZSI7DQpjb25zdCBhbGwgPSAiYWxsIjsNCg0KDQo= ------------BlKq31CYPBdTAKLNvjfMO1--
May 21 2009
On Thu, 21 May 2009 10:45:24 -0400, Robert Clipsham <robert octarineparrot.com> wrote:I recently came across this: version( BackendFoo ) {} else version( BackendBar ) {} else version( BackendCar ) {} else { pragma( msg, "Warning: backend version undefined" ); pragma( msg, "Attempting to guess backend" ); version( Windows ) { version = BackendFoo; pragma( msg, "Selected the Foo backend." ); } else version(...) { /* You get the idea */ } } However, when trying to compile I get the following error: Error: version BackendFoo defined after use What is the reasoning behind this? It could be extremely useful to have this functionality. The only reason I can think of for doing this is that this code could be evaluated after modules that depend on the version being defined, causing it not to work. Surely there would be a way around that? If it's not possible to fix this, what way would you recommend I get around this? The only idea I've come up with so far is to do: else { static assert( false, "Please compile with -version=Backend(Foo|Bar|Bar)" ); } Which is less than optimal.
Versions are intended to be predefined before usage. It's the same thing as using a variable before it's defined. The rational is, to flag errors to the user where he thinks forward referencing of versions works. Unfortunately, you have to do the following workaround: version(BackendFoo) { version=BackendFoo_;} else version(BackendBar) { version=BackendBar_;} else version(BackendCar) { version=BackendCar_;} else { version(Windows) {version=BackendFoo_;} } And now, you must use Backend*_ in your code. It should work, but it's ugly. Maybe Walter has a better method. -Steve
May 21 2009
Steven Schveighoffer wrote:Versions are intended to be predefined before usage. It's the same thing as using a variable before it's defined. The rational is, to flag errors to the user where he thinks forward referencing of versions works. Unfortunately, you have to do the following workaround: version(BackendFoo) { version=BackendFoo_;} else version(BackendBar) { version=BackendBar_;} else version(BackendCar) { version=BackendCar_;} else { version(Windows) {version=BackendFoo_;} } And now, you must use Backend*_ in your code. It should work, but it's ugly. Maybe Walter has a better method. -Steve
Unfortunately I thought this might be the case. Thanks.
May 21 2009
Tim Matthews wrote:I think this would be less ugly: template vers(char[] V) { mixin("version(" ~ V ~ ") { const bool vers = true; } else { const bool vers = false; }"); } static if(vers!("BackendFoo") || vers!("Windows")) { // } else static if(vers!("BackendBar")) { // } else static if (vers!("BackendCar")) { // } else { // } I would prefer the normal version statement to work like that directly though.
This still doesn't solve my problem though, all it does is remove the usage of the version statement, which seems... pointless :S
May 22 2009
Tim Matthews wrote:From what can I see you have a few different posssible versions but when no version is defined you can select a default version based on other stuff like windows operating system. Rather than modify the versions or add aditional to match the system you can create complex 'static if' statements which also are a compile time feature but can have other static ifs and logical comparisons like '&&' and '||'. When you have put the right checks in you can match your select target systems all within a single static if.
Ah, I see what you mean now, you don't mean to use this on its own, but rather use it along with other tests, so rather than using a version identifier it would resolve to something internally which could be tested in a static if... this would work nicely actually, thanks!
May 22 2009
On Fri, 22 May 2009 07:54:07 +1200, Robert Clipsham <robert octarineparrot.com> wrote:Steven Schveighoffer wrote:Versions are intended to be predefined before usage. It's the same thing as using a variable before it's defined. The rational is, to flag errors to the user where he thinks forward referencing of versions works. Unfortunately, you have to do the following workaround: version(BackendFoo) { version=BackendFoo_;} else version(BackendBar) { version=BackendBar_;} else version(BackendCar) { version=BackendCar_;} else { version(Windows) {version=BackendFoo_;} } And now, you must use Backend*_ in your code. It should work, but it's ugly. Maybe Walter has a better method. -Steve
Unfortunately I thought this might be the case. Thanks.
I think this would be less ugly: template vers(char[] V) { mixin("version(" ~ V ~ ") { const bool vers = true; } else { const bool vers = false; }"); } static if(vers!("BackendFoo") || vers!("Windows")) { // } else static if(vers!("BackendBar")) { // } else static if (vers!("BackendCar")) { // } else { // } I would prefer the normal version statement to work like that directly though.
May 21 2009
Robert Clipsham wrote:I recently came across this: version( BackendFoo ) {} else version( BackendBar ) {} else version( BackendCar ) {} else { pragma( msg, "Warning: backend version undefined" ); pragma( msg, "Attempting to guess backend" ); version( Windows ) { version = BackendFoo; pragma( msg, "Selected the Foo backend." ); } else version(...) { /* You get the idea */ } } However, when trying to compile I get the following error: Error: version BackendFoo defined after use What is the reasoning behind this? It could be extremely useful to have this functionality. The only reason I can think of for doing this is that this code could be evaluated after modules that depend on the version being defined, causing it not to work. Surely there would be a way around that?
Versions are like in functional programming, they are NOT variables. Once you've tested the existence of a non-existent version identifier, you've implicitly declared it. When there was a discussion about 'version' some time back, I made a proposal which (among other things) would require you to explicitly state that a particular version identifier is set from the command line; that would make this case clearer.
May 22 2009
On Fri, 22 May 2009 20:29:03 +1200, Robert Clipsham <robert octarineparrot.com> wrote:Tim Matthews wrote:I think this would be less ugly: template vers(char[] V) { mixin("version(" ~ V ~ ") { const bool vers = true; } else { const bool vers = false; }"); } static if(vers!("BackendFoo") || vers!("Windows")) { // } else static if(vers!("BackendBar")) { // } else static if (vers!("BackendCar")) { // } else { // } I would prefer the normal version statement to work like that directly though.
This still doesn't solve my problem though, all it does is remove the usage of the version statement, which seems... pointless :S
From what can I see you have a few different posssible versions but when no version is defined you can select a default version based on other stuff like windows operating system. Rather than modify the versions or add aditional to match the system you can create complex 'static if' statements which also are a compile time feature but can have other static ifs and logical comparisons like '&&' and '||'. When you have put the right checks in you can match your select target systems all within a single static if.
May 22 2009









"Tim Matthews" <tim.matthews7 gmail.com> 