digitalmars.D - Question about version ( ) keyword
- Vincent R (89/89) Mar 21 2016 Hi,
- Adam D. Ruppe (15/17) Mar 21 2016 That's exactly why it is done this way, so the platforms are
- Chris Wright (24/33) Mar 22 2016 That works where you are importing platform APIs. version(Posix) makes
- Joakim (4/10) Mar 21 2016 The language creator is against it, more info can be found in
- Kagamin (16/43) Mar 21 2016 Even shorter:
- Daniel Kozak via Digitalmars-d (4/43) Mar 21 2016 I do not see:
- Daniel Kozak via Digitalmars-d (44/123) Mar 21 2016 It is already has been sad why this does not work. But you can still do
- Nick Treleaven (3/6) Mar 23 2016 As a workaround, you can do it with static if and version strings:
Hi, When looking at core definitions like core.sys.posix.pthread I can see some "duplicated" code because it seems version doesn't support Or as we would do in C/C++ with #ifdefined. For instance if can read this: version( CRuntime_Glibc ) { enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version( FreeBSD ) { enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (OSX) { } else version (Solaris) { enum PTHREAD_BARRIER_SERIAL_THREAD = -2; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (CRuntime_Bionic) { } else { static assert(false, "Unsupported platform"); } When I see this code I cannot help thinking of something like: version( CRuntime_Glibc ) || version( FreeBSD ) || version (Solaris) { if(version(Solaris)) enum PTHREAD_BARRIER_SERIAL_THREAD = -2; else enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (OSX) ||version (CRuntime_Bionic) { } else { static assert(false, "Unsupported platform"); } I suppose language creators had good reasons to not allow it but I am a bit disapointed by the aspect of this language because some files are really verbose. However I understand that this limitation allow a clear separation between different platforms...
Mar 21 2016
On Monday, 21 March 2016 at 14:51:48 UTC, Vincent R wrote:However I understand that this limitation allow a clear separation between different platforms...That's exactly why it is done this way, so the platforms are clearly separated from each other and always grouped together for themselves. When writing these, we try to copy/paste it from the specific platform's documentation as a whole block so it is there and correct without accidentally assuming a Linux function is the same as a FreeBSD function (for example) just because a few of them were and got grouped in an OR block, but the rest weren't and got overlooked. Doing it separately makes sure we look each thing up for the specific platform to get it right. (Version does not support an or thing itself to force this, but still if you really wanted to, you can static if or set shared version identifiers, so it is possible, just the language and library guidelines don't want you doing it that way.)
Mar 21 2016
On Mon, 21 Mar 2016 15:01:27 +0000, Adam D. Ruppe wrote:On Monday, 21 March 2016 at 14:51:48 UTC, Vincent R wrote:That works where you are importing platform APIs. version(Posix) makes that a bit easier in some cases. And the general tactic is to wrap those APIs to be not platform-specific so you can omit version statements almost everywhere. But if you still find that you have things that need to be versioned out but much of the code is identical, another option is to use mixins: template DeclarationsForiOSAndAndroid() { extern(C) void foo(); extern(C) int bar(int i); } version (iOS) { mixin DeclarationsForiOSAndAndroid; extern(C) int iOSVersion(); } version (Android) { mixin DeclarationsForiOSAndAndroid; extern(C) int androidVersion(); } There will rarely be a reason to do this, but you might find it handy some day.However I understand that this limitation allow a clear separation between different platforms...That's exactly why it is done this way, so the platforms are clearly separated from each other and always grouped together for themselves. When writing these, we try to copy/paste it from the specific platform's documentation as a whole block
Mar 22 2016
On Monday, 21 March 2016 at 14:51:48 UTC, Vincent R wrote:Hi, When looking at core definitions like core.sys.posix.pthread I can see some "duplicated" code because it seems version doesn't support Or as we would do in C/C++ with #ifdefined. For instance if can read this: [...]The language creator is against it, more info can be found in forum threads like this one: http://forum.dlang.org/thread/n0u5v3$1lsh$1 digitalmars.com
Mar 21 2016
On Monday, 21 March 2016 at 14:51:48 UTC, Vincent R wrote:When I see this code I cannot help thinking of something like: version( CRuntime_Glibc ) || version( FreeBSD ) || version (Solaris) { if(version(Solaris)) enum PTHREAD_BARRIER_SERIAL_THREAD = -2; else enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (OSX) ||version (CRuntime_Bionic) { } else { static assert(false, "Unsupported platform"); }Even shorter: version(Solaris) enum PTHREAD_BARRIER_SERIAL_THREAD = -2; else enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
Mar 21 2016
Dne 21.3.2016 v 18:18 Kagamin via Digitalmars-d napsal(a):On Monday, 21 March 2016 at 14:51:48 UTC, Vincent R wrote:I do not see: static assert(false, "Unsupported platform"); so no, it is not shorter just wrong ;-)When I see this code I cannot help thinking of something like: version( CRuntime_Glibc ) || version( FreeBSD ) || version (Solaris) { if(version(Solaris)) enum PTHREAD_BARRIER_SERIAL_THREAD = -2; else enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (OSX) ||version (CRuntime_Bionic) { } else { static assert(false, "Unsupported platform"); }Even shorter: version(Solaris) enum PTHREAD_BARRIER_SERIAL_THREAD = -2; else enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
Mar 21 2016
Dne 21.3.2016 v 15:51 Vincent R via Digitalmars-d napsal(a):Hi, When looking at core definitions like core.sys.posix.pthread I can see some "duplicated" code because it seems version doesn't support Or as we would do in C/C++ with #ifdefined. For instance if can read this: version( CRuntime_Glibc ) { enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version( FreeBSD ) { enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (OSX) { } else version (Solaris) { enum PTHREAD_BARRIER_SERIAL_THREAD = -2; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (CRuntime_Bionic) { } else { static assert(false, "Unsupported platform"); } When I see this code I cannot help thinking of something like: version( CRuntime_Glibc ) || version( FreeBSD ) || version (Solaris) { if(version(Solaris)) enum PTHREAD_BARRIER_SERIAL_THREAD = -2; else enum PTHREAD_BARRIER_SERIAL_THREAD = -1; int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (OSX) ||version (CRuntime_Bionic) { } else { static assert(false, "Unsupported platform"); } I suppose language creators had good reasons to not allow it but I am a bit disapointed by the aspect of this language because some files are really verbose. However I understand that this limitation allow a clear separation between different platforms...It is already has been sad why this does not work. But you can still do something like this (or maybe even something better(shorter)): version(CRuntime_Glibc) { enum PTHREAD_BARRIER_SERIAL_THREAD = -1; version = WhatEver1; } else version(FreeBSD) { enum PTHREAD_BARRIER_SERIAL_THREAD = -1; version = WhatEver1; } else version (OSX) { version = WhatEver2; } else version (Solaris) { enum PTHREAD_BARRIER_SERIAL_THREAD = -2; version = WhatEver1; } else version (CRuntime_Bionic) { version = WhatEver2; } version (WhatEver1) { int pthread_barrier_destroy(pthread_barrier_t*); int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint); int pthread_barrier_wait(pthread_barrier_t*); int pthread_barrierattr_destroy(pthread_barrierattr_t*); int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); int pthread_barrierattr_init(pthread_barrierattr_t*); int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); } else version (WhatEver2) else { static assert(false, "Unsupported platform"); } But to be fair I still prefer original code because it is obvious, which platform support what :)
Mar 21 2016
On Monday, 21 March 2016 at 14:51:48 UTC, Vincent R wrote:version( CRuntime_Glibc ) || version( FreeBSD ) || version (Solaris) {As a workaround, you can do it with static if and version strings: http://forum.dlang.org/post/op.vkshabecot0hzo las-miodowy
Mar 23 2016