Re: Unexpected result with -betterC
On Sunday, 3 November 2024 at 19:47:31 UTC, monkyyy wrote: [...] Id expect this to fail, but nothing I see in yours ```d string foo="foo"; foo~="bar"; ``` []'s are both slices and dynamic arrays depending on use, theres a debate about that decision(im of the opinion a `[?]` should be a dynamic array and clean up the api), but the current situation will only break on appends Surely the line: ``` string Scrn = "OPO NAM='DspVar1' POS='1,1' VAR=('IntVar1','I');E"; ``` creates, by the definition of 'string', a dynamic array?
Unexpected result with -betterC
The two fragments below compiled and ran as expected using dmd -betterC under Windows. ``` string Scrn = "OPO NAM='DspVar1' POS='1,1' VAR=('IntVar1','I');E"; printf("\nWR_Createtest entered.\n"); OpStructFstPtr = WR_CreateFormatFile(Scrn); ``` ``` OpStruct* WR_CreateFormatFile(string parm_Format) { import core.stdc.stdio: printf; import core.stdc.stdlib: malloc; OpStruct* FstOpStructPtr; if (parm_Format[0..3] == "OPO"[0..3]) { printf("OPO Found.\n"); } else { printf("OPO NOT Found.\n"); } if (parm_Format[$-1..$] == "E"[0..1]) { printf("E Found.\n"); } else { printf("E NOT Found.\n"); } ``` However, the docs say dynamic arrays are not allowed with betterC, and 'string' implies a dynamic array. So I expected DMD to complain that my code was invalid. Any ideas?
Re: ImportC question
On Wednesday, 30 October 2024 at 09:21:55 UTC, ryuukk_ wrote: On Tuesday, 29 October 2024 at 20:26:58 UTC, DLearner wrote: On Tuesday, 29 October 2024 at 18:57:15 UTC, Salih Dincer wrote: On Monday, 28 October 2024 at 20:56:03 UTC, DLearner wrote: Just trying ImportC under Windows 10: ```c #include int main() { printf("Hello world.\n"); return 0; } ``` Produces ``` dmd hello.c failed launching cl.exe /P /Zc:preprocessor /PD /nologo hello.c /FIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h /Fihello.i Error: C preprocess command cl.exe failed for file hello.c, exit status 1 ``` DMD Compiler version? SDB@79 ``` C:\Users\SoftDev>dmd DMD64 D Compiler v2.106.0-dirty ``` update your compiler, latest version is: 2.109.1 then, and only then you can start wondering what's broken Now upgraded. 1. I noticed that the installation process also installed _both_ Visual Studio 2019 _and_ Visual Studio 2022. Is one of these preferred? 2. With 2019: ``` C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>dmd C:\Users\SoftDev\Documents\BDM\Projects\IT\C\hello.c C:\Program Files (x86)\Microsoft Visual Studio\2019\Community> ``` ie silence (and no 'hello' files produced either). 3. With 2022: ``` C:\Program Files\Microsoft Visual Studio\2022\Community>dmd C:\Users\SoftDev\Documents\BDM\Projects\IT\C\hello.c C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\shared\driverspecs.h(381): warning C4005: '_Kernel_acquires_resource_': macro redefinition C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\shared\no_sal2.h(876): note: see previous definition of '_Kernel_acquires_resource_' C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\shared\driverspecs.h(391): warning C4005: '_Kernel_releases_resource_': macro redefinition ``` and a large number of similar messages.
Re: ImportC question
On Tuesday, 29 October 2024 at 18:57:15 UTC, Salih Dincer wrote: On Monday, 28 October 2024 at 20:56:03 UTC, DLearner wrote: Just trying ImportC under Windows 10: ```c #include int main() { printf("Hello world.\n"); return 0; } ``` Produces ``` dmd hello.c failed launching cl.exe /P /Zc:preprocessor /PD /nologo hello.c /FIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h /Fihello.i Error: C preprocess command cl.exe failed for file hello.c, exit status 1 ``` DMD Compiler version? SDB@79 ``` C:\Users\SoftDev>dmd DMD64 D Compiler v2.106.0-dirty ```
Re: ImportC question
On Tuesday, 29 October 2024 at 15:49:13 UTC, ryuukk_ wrote: On Tuesday, 29 October 2024 at 15:14:24 UTC, DLearner wrote: On Tuesday, 29 October 2024 at 12:42:49 UTC, Lance Bachmeier wrote: On Tuesday, 29 October 2024 at 12:23:06 UTC, DLearner wrote: However, there is still a problem: ``` dmd hello.c C:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h(134): fatal error C1034: sal.h: no include path set Error: C preprocess command cl.exe failed for file hello.c, exit status 2 ``` which looks like dmd found cl.exe, but did not supply it with all the data it required. I don't do much on Windows, so I was having trouble with getting the VS stuff installed correctly. I borrowed this command from the Swift installation guide and everything worked: ``` winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom "--add Microsoft.VisualStudio.Component.Windows11SDK.22000 --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ``` Thanks for the idea. The winget installation completed without issues. Unfortunately, 'dmd hello.c' produced the same error message as before. you need to invoke that command inside this windoze stupid thing: https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022 Similar message from Powershell: ``` PS C:\Users\SoftDev\Documents\BDM\projects\it\c> dmd hello.c C:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h(134): fatal error C1034: sal.h: no include path set Error: C preprocess command C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\bin\HostX64\x64\cl.exe failed for file hello.c, exit status 2 ```
Re: ImportC question
On Tuesday, 29 October 2024 at 12:42:49 UTC, Lance Bachmeier wrote: On Tuesday, 29 October 2024 at 12:23:06 UTC, DLearner wrote: However, there is still a problem: ``` dmd hello.c C:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h(134): fatal error C1034: sal.h: no include path set Error: C preprocess command cl.exe failed for file hello.c, exit status 2 ``` which looks like dmd found cl.exe, but did not supply it with all the data it required. I don't do much on Windows, so I was having trouble with getting the VS stuff installed correctly. I borrowed this command from the Swift installation guide and everything worked: ``` winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom "--add Microsoft.VisualStudio.Component.Windows11SDK.22000 --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64" ``` Thanks for the idea. The winget installation completed without issues. Unfortunately, 'dmd hello.c' produced the same error message as before.
Re: ImportC question
On Tuesday, 29 October 2024 at 00:10:17 UTC, Richard (Rikki) Andrew Cattermole wrote: https://github.com/dlang/dmd/blob/dbba866c71db5e1222a1b631b3e910f1a0811732/compiler/src/dmd/link.d#L1332 cl.exe comes from Visual Studio (MSVC). If you haven't got it installed, that'll be why. Otherwise its related to dmd not being able to find it. Thank you. I installed Visual Studio 2022, proved the existence of cl.exe, and added the location to the search path. However, there is still a problem: ``` dmd hello.c C:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h(134): fatal error C1034: sal.h: no include path set Error: C preprocess command cl.exe failed for file hello.c, exit status 2 ``` which looks like dmd found cl.exe, but did not supply it with all the data it required.
ImportC question
Just trying ImportC under Windows 10: ``` #include int main() { printf("Hello world.\n"); return 0; } ``` Produces ``` dmd hello.c failed launching cl.exe /P /Zc:preprocessor /PD /nologo hello.c /FIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h /Fihello.i Error: C preprocess command cl.exe failed for file hello.c, exit status 1 ``` Any ideas? Best regards
Re: Indirect access to variables.
On Friday, 29 December 2023 at 21:25:44 UTC, user1234 wrote: [...] Thanks, and the ideas are useful, but please see below, suppose: ``` void main() { size_t var1 = 1; size_t var2 = 3; size_t var3 = 5; // ... Many other variables defined. char[4] VarName; // ... // And some complicated logic finishes: VarName = cast(char[4])("var2"); // _Without_ previously storing the addresses of // all the 'var' variables, how do I get access // to the variable currently (run-time) named in VarName? // // Is there a compiler-provided // 'introspection' function that would do this? // // Labouring the point: If there is an int variable intVar, // whose name ("intVar") is held in a string variable strVar, // then there is a compiler function __fnAddrVar() such that // assert(__fnAddrVar(strVar) == &intVar) // is true? } ```
Indirect access to variables.
Compile-time: Is there a 'foo1' that yields 1 from the snippet below? ``` void main() { import std.stdio; size_t var1 = 1; char[4] Txt = cast(char[4])("var1"); writeln(foo1(Txt)); } ``` Similarly, execution-time, is there a foo2 that wields 2 from the snippet below: ``` void main() { import std.stdio; size_t var2 = 2; char[4] Txt; // Txt = various things at run-time; // But finally: Txt = cast(char[4])("var2"); writeln(foo2(Txt)); } ```
Re: Change to unittest?
On Thursday, 21 December 2023 at 10:38:16 UTC, DLearner wrote: [...] And now, returning to the problem after several hours Christmas shopping, everything seems to work perfectly!
Change to unittest?
This applies to dmd version v2.106.0-dirty under Windows. Module containing several functions with unittests, no 'main' function. Was testing ok some time ago, producing '1/1 modules PASSED unittests' message. Today, ``` dmd -main -unittest -run ``` produced nothing, just a return to the command prompt. (FWIW no corresponding .obj or .exe files in directory) So, reversed one of the unittests to produce failure, and repeated. Same result. (Suggesting unittests not being run). Then reset unittest, and ran without the -run. Saw .obj and .exe files. Ran .exe: no messages. Then (maybe this sheds some light) changed the test to produce failure, ran without -run, then ran resulting .exe And got ``` 1/1 modules FAILED unittests ``` Has there been some sort of change to the -unittest function?
Compiler analysis fault?
The code below fails to compile with Error: function `test1.foo` no `return exp;` or `assert(0);` at end of function unless the commented-out assert(0) is included. Please, what rule of D is being broken? foo does not unconditionally loop, and the only places where foo returns, it returns with a bool. ``` bool foo() { import std.stdio; int I1; int nogoagain; while(true) { I1 = 2; while( I1 <= 10) { if (I1 != 5) { } else { goto L2; } I1 = I1 + 1; } return true; L2:; readf(" %s", nogoagain); if (nogoagain == 5) { return false; } else { } } // assert(0); } void main() { import std.stdio; writeln("A"); writeln(foo()); } ```
Re: mixin under -betterC
On Sunday, 26 November 2023 at 15:35:39 UTC, Adam D Ruppe wrote: On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote: string mxnTest(string strVar1, string strVar2) { return `(int Var1, int Var2) { if (Var1 > Var2) { return true; } else { return false; } }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`; } ``` This function exists at runtime. Another module could, in theory, import it and call it. A shared library could, in theory, export it. You used it at compile time, but the function is available for other users too. betterC doesn't know the difference between theory and practice. From your comments and others on this thread: ``` // Test harness extern(C) void main() { import core.stdc.stdio : printf; import testmod; bool FirstVarGreater; int Var_A = 6; int Var_B = 5; FirstVarGreater = mixin(mxnTest("Var_A", "Var_B")); if (FirstVarGreater) { printf("First Var is Greater\n"); } else { printf("First Var is not Greater\n"); } } // testmod string mxnTest(string strVar1, string strVar2) { if (__ctfe) { return `(int Var1, int Var2) { if (Var1 > Var2) { return true; } else { return false; } }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`; } else { return ``; } } ``` Works, avoid templates + -betterC compliant, but to me clumsy.
Anonymous function scope issue?
The two little demo scripts: ``` string mxnAdd()(string strName) { return `(typeof(` ~ strName ~ `) Pld) { import core.stdc.stdlib : malloc; struct Mst { typeof(` ~ strName ~ `) Pld; int I1; } Mst*MstPtr; MstPtr = cast(Mst*)(malloc(Mst.sizeof)); if (MstPtr is null) { return null; } else { } MstPtr.Pld= Pld; MstPtr.I1 = 1; return &MstPtr.Pld; }(` ~ strName ~ `)`; } void main() { // Compile-time. // Establish simple variables: int IntFld1; int IntFld2; // Define a structure: struct X { int Fld1; int Fld2; } // Establish a structure variable: XXVar; // Establish a pointer to the structure: X* XPtr; // Execution-time. // Load variables: IntFld1 = 3; IntFld2 = 4; // Load the structure variable members: XVar.Fld1 = IntFld1; XVar.Fld2 = IntFld2; // Now execute the command: XPtr = mixin(mxnAdd("XVar")); // Now check the results: assert(XPtr !is null); // Returned pointer non-null, // so shows new datastructure added. assert(XPtr.Fld1 == 3); // Shows new datastructure holds original data item. assert(XPtr.Fld2 == 4); // Shows new datastructure holds original data item. } ``` and ``` string mxnAdd()(string strName) { return `(typeof(` ~ strName ~ `) XVar) { import core.stdc.stdlib : malloc; struct Mst { typeof(` ~ strName ~ `) XVar; int I1; } Mst*MstPtr; MstPtr = cast(Mst*)(malloc(Mst.sizeof)); if (MstPtr is null) { return null; } else { } MstPtr.XVar= XVar; MstPtr.I1 = 1; return &MstPtr.XVar; }(` ~ strName ~ `)`; } void main() { // Compile-time. // Establish simple variables: int IntFld1; int IntFld2; // Define a structure: struct X { int Fld1; int Fld2; } // Establish a structure variable: XXVar; // Establish a pointer to the structure: X* XPtr; // Execution-time. // Load variables: IntFld1 = 3; IntFld2 = 4; // Load the structure variable members: XVar.Fld1 = IntFld1; XVar.Fld2 = IntFld2; // Now execute the command: XPtr = mixin(mxnAdd("XVar")); // Now check the results: assert(XPtr !is null); // Returned pointer non-null, // so shows new datastructure added. assert(XPtr.Fld1 == 3); // Shows new datastructure holds original data item. assert(XPtr.Fld2 == 4); // Shows new datastructure holds original data item. } ``` Are identical, except that, in the second demo, one variable name in the mixin function was changed to be the same as a variable name in the main function (it would obviously be dangerous to do this deliberately, but this happened by accident). The first demo runs OK. The second fails with a 'circular reference' error. My question is simply why this is a problem at all - the scope of any names used in the mixin function should surely not extend beyond that function, so no clash should arise?
Re: anonymous structs within structs
On Tuesday, 5 December 2023 at 00:31:35 UTC, H. S. Teoh wrote: On Mon, Dec 04, 2023 at 11:46:45PM +, DLearner via Digitalmars-d-learn wrote: [...] Basically, B corresponds to the whole record (and only a whole record can be read). But the task only requires Var1 and Var2, the last two fields on the record. By putting all the irrelevant fields into A, and defining B as above, program remains unpolluted with data it does not need. [...] Sounds like what you need is something like this: struct Record { struct UnimportantStuff { ... } UnimportantStuff unimportant; struct ImportantStuff { ... } ImportantStuff important; } ImportantStuff readData() { Record rec = readData(...); // read entire record return rec.important; // discard unimportant stuff } int main() { ... ImportantStuff data = readData(); // only important stuff returned processData(data); ... } T I think that what you propose would work. However, what I was really interested in was finding a way (using your example) of not instantiating UnimportantStuff anywhere. Your suggestion instantiates it at: ``` UnimportantStuff unimportant; ``` I was thinking (again using your example) of something like: ``` struct UnimportantStuff { ... } struct Record { UnimportantStuff.sizeof; struct ImportantStuff { ... } ImportantStuff important; } ``` But was concerned about possible alignment issues.
Re: anonymous structs within structs
On Monday, 4 December 2023 at 23:16:27 UTC, thinkunix wrote: DLearner via Digitalmars-d-learn wrote: On Monday, 4 December 2023 at 21:55:29 UTC, Mike Shah wrote: [...] Is something like this what you had in mind? ``` void main() { import std.stdio; mixin template A() { int I1; int I2; char X; } struct B { mixin A; int Var1; int Var2; } B someObject; writeln(someObject.I1); writeln(someObject.I2); } ``` More like ``` B someObject; writeln(someObject.Var1); writeln(someObject.Var2); ``` In the areas where B is used, don't want I1 or I2 to be visible. If you don't want members of A to be visible in B, why are you even including struct A as part of B? Why wouldn't you use a class and make the members private? I'm certainly not a D expert and I don't know your use case so maybe I'm missing something. scot Basically, B corresponds to the whole record (and only a whole record can be read). But the task only requires Var1 and Var2, the last two fields on the record. By putting all the irrelevant fields into A, and defining B as above, program remains unpolluted with data it does not need.
Re: anonymous structs within structs
On Monday, 4 December 2023 at 21:55:29 UTC, Mike Shah wrote: [...] Is something like this what you had in mind? ``` void main() { import std.stdio; mixin template A() { int I1; int I2; char X; } struct B { mixin A; int Var1; int Var2; } B someObject; writeln(someObject.I1); writeln(someObject.I2); } ``` More like ``` B someObject; writeln(someObject.Var1); writeln(someObject.Var2); ``` In the areas where B is used, don't want I1 or I2 to be visible.
anonymous structs within structs
Suppose we need a construct like: ``` void main() { struct A { int I1; int I2; char X; } struct B { A Dummy; int Var1; int Var2; } } ``` But do not want to give an explicit name (like 'Dummy' above) to the A struct held within the B struct. Just removing 'Dummy' does not work (Error: no identifier for declarator `A`). Nor does replacing 'Dummy' with {} Suggestions?
mixin issue
The code: ``` void main() { struct SB { char SBChrFld1; char SBChrFld2; int SBIntFld1; int SBIntFld2; } SB SBVar; SB* wkSBPtr; void* StartPtr1 = null; mixin(mxnDelMbr("StartPtr1", "wkSBPtr")); return; } string mxnDelMbr()(string strStartPtr, string strPLPtr) { return `(void* StartPtr, typeof(` ~ strPLPtr ~ `) PLPtr) { }(` ~ strStartPtr ~ `,` ~ strPLPtr ~ `)`; } ``` Fails with: ``` Error: found `End of File` when expecting `;` following statement ``` If an extra ; is added: ``` }(` ~ strStartPtr ~ `,` ~ strPLPtr ~ `);`; ``` it works but doesn't seem correct. Further, example above cloned from several other similar examples, which not only work, but if ';' introduced in corresponding place, dmd complains with empty statement deprecation. FWIW only difference identified between successful examples and this one, is that other functions all return something, this one does not. Suggestions?
Re: 'typeof' question
On Tuesday, 28 November 2023 at 18:43:37 UTC, Adam D Ruppe wrote: On Tuesday, 28 November 2023 at 18:41:49 UTC, DLearner wrote: A* A_Ptr; struct B { int BFld2; typeof(A_Ptr)[0..($-1)] ASUB; // Idea is ASUB of type A, from A_Ptr of type A*. I think what you really want is typeof(*A_Ptr) ASUB; the typeof thing returns the type you'd get from the code inside Thanks - worked.
'typeof' question
Trying to manipulate 'typeof' return strings, preferably at compile-time. e.g. to produce struct B below (intended to have an A sub-struct), from A_Ptr alone. ``` struct A { int AFld1; } A* A_Ptr; struct B { int BFld2; typeof(A_Ptr)[0..($-1)] ASUB; // Idea is ASUB of type A, from A_Ptr of type A*. } ``` But this fails with 'can only slice tuple types...'. Suggestions?
Re: mixin under -betterC
On Thursday, 23 November 2023 at 17:02:58 UTC, Paul Backus wrote: [...] This is a known limitation: https://issues.dlang.org/show_bug.cgi?id=23637 [...] Sorry to come back to this, but the reference above suggests _not_ a bug in the compiler. If not a bug in the compiler, please, what is going on? I repeat that the only possible trigger I see for the GC are the ~ that happen at compile, not run, time.
Re: mixin under -betterC
On Thursday, 23 November 2023 at 18:54:09 UTC, Julian Fondren wrote: [...] The `enum` answer? [...] No, the 'template' answer. To me, if the 'template' suggestion worked (as it did), then my simple mixin (as in my original post) should also work.
Re: mixin under -betterC
On Thursday, 23 November 2023 at 17:03:29 UTC, Julian Fondren wrote: On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote: Why is this so, bearing in mind the concatenations are executed at compile, not run, time? If you compile without -betterC, it'll work, but if you examine the result you'll find that the mxnTest function is still compiled into the result. D makes it so convenient to use functions at compile-time that there's no clear distinction for functions that should only exist at compile-time. Make mxnTest a template: ```d string mxnTest()(string strVar1, string strVar2) { ^^ ``` I tried what you suggested, and with no other changes it compiled and ran correctly. Thanks! I just find it surprising that your suggestion worked, but the (slightly simpler) earlier version did not.
mixin under -betterC
Code below is intended to test simple mixin with lambda function under -betterC. Works with full-D, but fails with 'needs GC' errors under -betterC. Why is this so, bearing in mind the concatenations are executed at compile, not run, time? ``` // Test harness extern(C) void main() { import core.stdc.stdio : printf; import testmod; bool FirstVarGreater; int Var_A = 4; int Var_B = 3; FirstVarGreater = mixin(mxnTest("Var_A", "Var_B")); if (FirstVarGreater) { printf("First Var is Greater\n"); } else { printf("First Var is not Greater\n"); } } // testmod string mxnTest(string strVar1, string strVar2) { return `(int Var1, int Var2) { if (Var1 > Var2) { return true; } else { return false; } }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`; } ```
Re: import issue?
On Wednesday, 22 November 2023 at 16:51:54 UTC, Richard (Rikki) Andrew Cattermole wrote: On 23/11/2023 5:34 AM, DLearner wrote: Is the encapsulation issue resolved if the struct itself is held in another module, and imported from that module into both the 'main' and 'Ex_mod' files? Each module is its own encapsulation unit. As long as you are using the same distinct type in both modules, the issues are resolved. Where the distinct type is defined does not matter for matching of function parameters. OK thanks.
Re: import issue?
On Wednesday, 22 November 2023 at 16:11:03 UTC, Richard (Rikki) Andrew Cattermole wrote: You have two ``SA`` structs, each in different encapsulations. Each of them are different, even if they have similar members. In D types that look the same do not combine, they are distinct. You can see this by comparing the mangling of each. ``pragma(msg, SA.mangleof);`` Is the encapsulation issue resolved if the struct itself is held in another module, and imported from that module into both the 'main' and 'Ex_mod' files?
import issue?
Please, Why does: ``` // Test module Ex_mod struct SA { int SAIntFld1; int SAIntFld2; } bool AddEle(ref void* StartPtr, SA PayLoad1) { import core.stdc.stdlib : malloc; struct Ele { SA PayLoad; Ele* EleNxtPtr; Ele* ElePrvPtr; } Ele*ElePtr; Ele* wkElePtr; return true; } ``` imported into: ``` // Test harness struct SA { int SAIntFld1; int SAIntFld2; } void main() { import std.stdio: writeln; import Ex_mod; SA SAVar; void* SA_StartPtr = null; SAVar.SAIntFld1 = 3; SAVar.SAIntFld2 = -5; if (AddEle(SA_StartPtr, SAVar)) { writeln("Element linked"); } else { writeln("Element not linked"); } } ``` Fail with: ``` ex_main.d(21): Error: function `Ex_mod.AddEle(ref void* StartPtr, SA PayLoad1)` is not callable using argument types `(void*, SA)` ex_main.d(21):cannot pass argument `SAVar` of type `ex_main.SA` to parameter `Ex_mod.SA PayLoad1` ``` When eliminating the import via: ``` // Test harness struct SA { int SAIntFld1; int SAIntFld2; } bool AddEle(ref void* StartPtr, SA PayLoad1) { import core.stdc.stdlib : malloc; struct Ele { SA PayLoad; Ele* EleNxtPtr; Ele* ElePrvPtr; } Ele*ElePtr; Ele* wkElePtr; return true; } void main() { import std.stdio: writeln; // import Ex_mod; SA SAVar; void* SA_StartPtr = null; SAVar.SAIntFld1 = 3; SAVar.SAIntFld2 = -5; if (AddEle(SA_StartPtr, SAVar)) { writeln("Element linked"); } else { writeln("Element not linked"); } } ``` works correctly?
Re: static if - unexpected results
On Friday, 23 June 2023 at 16:51:16 UTC, Ali Çehreli wrote: On 6/23/23 07:22, DLearner wrote: >`} else static if (__traits(isPOD, typeof(` ~ VarName ~ `))) {` ~ Regardless, you can also use the 'is' expression with the 'struct' keyword. If T is a struct, is (T == struct) that will produce true at compile time. Ali Thanks for this - I can confirm it works.
Re: static if - unexpected results
On Friday, 23 June 2023 at 15:48:44 UTC, H. S. Teoh wrote: On Friday, 23 June 2023 at 15:22:36 UTC, DLearner wrote: On Friday, 23 June 2023 at 14:31:45 UTC, FeepingCreature wrote: On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote: [...] ``` static assert(__traits(isPOD, int)); // ok. static assert(__traits(isPOD, byte)); // ok. ``` It's a bug in either the spec or the compiler. I am using ``` DMD64 D Compiler v2.103.0-dirty ``` under ``` Windows [Version 10.0.19045.3086] ``` Do I need to report this anywhere? Tested your original code on latest dmd git master, here's the output: d char1 is a char int1 is a struct foovar1 is a struct byte1 is a struct Looks like there isn't a problem? Or at least, it's now fixed in git master. Which exact version of dmd are you using? Did you download from dlang.org or did you build your own? --T Probably I misunderstand, but to me: ``` int1 is a struct ``` and ``` byte1 is a struct ``` are both errors. The 'struct' test is being triggered for things that are not structs.
Re: static if - unexpected results
On Friday, 23 June 2023 at 14:31:45 UTC, FeepingCreature wrote: On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote: [...] ``` static assert(__traits(isPOD, int)); // ok. static assert(__traits(isPOD, byte)); // ok. ``` It's a bug in either the spec or the compiler. I am using ``` DMD64 D Compiler v2.103.0-dirty ``` under ``` Windows [Version 10.0.19045.3086] ``` Do I need to report this anywhere?
static if - unexpected results
Hi Was looking for compile-time detection of a struct variable. However, the following test code gave the two 'FAILS' shown below. Comments? ``` void main() { import std.stdio : writeln; import std.traits; string mxnTst(string VarName) { return `static if (is(typeof(` ~ VarName ~ `) == char)) {` ~ `writeln("` ~ VarName ~ ` ", " is a char");` ~ `} else static if (__traits(isPOD, typeof(` ~ VarName ~ `))) {` ~ `writeln("` ~ VarName ~ ` ", " is a struct");` ~ `} else static if (is(typeof(` ~ VarName ~ `) == int)) {` ~ `writeln("` ~ VarName ~ ` ", " is an int");` ~ `} else {` ~ `static assert(false, "mxnTst Variable '` ~ VarName ~ `' is of unknown type");` ~ `}` ; } char char1; int int1; byte byte1; struct foo { int fooint; char foochar; } foo foovar1; mixin(mxnTst("char1")); // Expected: char1 is a char. Actual: char1 is a char. (ok) mixin(mxnTst("int1"));// Expected: int1 is an int. Actual: int1 is a struct. (FAIL) mixin(mxnTst("foovar1")); // Expected: foovar1 is a struct. Actual: foovar1 is a struct. (ok) mixin(mxnTst("byte1")); // Expected: Run to fail with the static assert message. Actual: byte1 is a struct. (FAIL) } ```
Re: compile-time detection of all pointer types in one test
On Sunday, 11 June 2023 at 21:32:11 UTC, Andy wrote: [...] void main() { import std.stdio; struct foo {} foo* fooptr; static if (is(typeof(fooptr) == T*, T)) writeln("fooptr is a pointer to a ", T.stringof); else writeln("fooptr is not a pointer"); } Unfortunately, testing more than one variable: ``` void main() { import std.stdio; struct foo1 {int foo1int; char foo1char;} foo1* foo1ptr; struct foo2 {int foo2int; char foo2char;} foo2* foo2ptr; static if (is(typeof(foo1ptr) == T*, T)) writeln("foo1ptr is a pointer to a ", T.stringof); else writeln("foo1ptr is not a pointer"); static if (is(typeof(foo2ptr) == T*, T)) writeln("foo2ptr is a pointer to a ", T.stringof); else writeln("foo2ptr is not a pointer"); } ``` produced ``` static_if_ex05.d(16): Error: declaration `T` is already defined static_if_ex05.d(11):`alias` `T` is defined here ```
assert/static assert message format difference
Only a small thing, but is it intended that: ``` void main() { // static assert (false, "Static Assert triggered"); assert(false, "Assert triggered"); } ``` produces ``` core.exception.AssertError@staticassertex01.d(4): Assert triggered ``` but removing the // produces ``` staticassertex01.d(3): Error: static assert: "Static Assert triggered" ``` ie message surrounded by double-quotes?
compile-time detection of all pointer types in one test
Please consider: ``` void main() { import std.stdio; struct foo { int foo1; char foo2; } foo* fooptr; void* genptr; static if (is(typeof(fooptr) == void*)) writeln("fooptr is void*"); else writeln("fooptr is not void*"); static if (is(typeof(fooptr) == foo*)) writeln("fooptr is foo*"); else writeln("fooptr is not foo*"); static if (is(typeof(genptr) == void*)) writeln("genptr is void*"); else writeln("genptr is not void*"); } ``` which produces: ``` fooptr is not void* fooptr is foo* genptr is void* ``` Since `void*` variables accept _all_ pointer types, I expected to see `fooptr is void*`. Is there any way of picking up, at compile-time, all pointer types in one test?
Re: unittest under betterC
On Monday, 5 June 2023 at 18:22:45 UTC, Ernesto Castellotti wrote: [...] It's not so easy to deal automatically in case of multiple modules _multiple modules_ The following code, in a batch (.bat) file, works for me: ``` @echo off :loop if [%1]==[] goto loopexit type .\%1.d > .\__temp_%1.d echo extern(C) void main() { static foreach(u; __traits(getUnitTests, __traits(parent, main))) u();} >> .\__temp_%1.d dmd -betterC -unittest -i -run .\__temp_%1.d del .\__temp_%1.d shift goto loop :loopexit ```
Re: unittest under betterC
On Monday, 5 June 2023 at 14:25:33 UTC, Mike Parker wrote: [...] The docs say it should work: https://dlang.org/spec/betterc.html#unittests [...] Thank you for the link, can confirm that: ``` int foo() { return 4; } unittest { assert(foo() != 4, "!= Assert triggered."); assert(foo() == 4, "== Assert triggered."); } extern(C) void main() { static foreach(u; __traits(getUnitTests, __traits(parent, main))) u(); } ``` run via: ``` dmd -betterC -unittest -i -run foo2 ``` works as expected. However, as a suggestion to create a consistent experience with 'Full D', should not the combination of '-main' and '-betterC' cause the generation and attachment of the boilerplate code ``` extern(C) void main() { static foreach(u; __traits(getUnitTests, __traits(parent, main))) u(); } ``` to a source file containing just the original function and it's unittests?
Re: unittest under betterC
On Monday, 5 June 2023 at 03:42:20 UTC, ryuukk_ wrote: [...] I don't know how all this works, ... For what it is worth, running _both_ the above code fragments with: ``` dmd -main -unittest -i -run foo ``` (ie removing the -betterC flag) produces: ``` foo.d(8): [unittest] != Assert triggered. 1/1 modules FAILED unittests ``` which is what was expected.
unittest under betterC
Neither: ``` extern(C) int foo() { return 4; } unittest { assert(foo() != 4, "!= Assert triggered."); assert(foo() == 4, "== Assert triggered."); } ``` Nor: ``` int foo() { return 4; } unittest { assert(foo() != 4, "!= Assert triggered."); assert(foo() == 4, "== Assert triggered."); } ``` Triggers anything with: ``` dmd -betterC -main -unittest -i -run foo ``` Any ideas?
D style - member functions
Consider: ``` struct S1 { int A; int B; int foo() { return(A+B); } } struct S2 { int A; int B; } int fnAddS2(S2 X) { return (X.A + X.B); } void main() { import std.stdio : writeln; S1 Var1 = S1(1, 2); writeln("Total Var1 = ", Var1.foo()); S2 Var2 = S2(1, 2); writeln("Total Var2 = ", fnAddS2(Var2)); return; } ``` Of the two ways shown of producing the total from the same underlying structure, which is the better style? Further, do we care about the situation where there are many variables of type 'S', which presumably means the function code generated from S1 gets duplicated many times, but not so with S2?
Re: ImportC issue?
On Wednesday, 19 April 2023 at 14:42:44 UTC, bachmeier wrote: [...] My understanding (from my occasional use of Windows) is that DMD installs the Community Edition of Visual Studio. That should solve your original issue, and you shouldn't need to mess with sppn.exe. Well it took a little while, but I can confirm that if you have a D function like: ``` extern(C) void DCallee() { import core.stdc.stdio : printf; printf("Entered DCallee.\n"); printf("Exiting DCallee.\n"); } ``` called from a C function like: ``` // C Master calling D (under -betterC restrictions). #include extern void DCallee(); int main() { printf("MastC Entered.\n"); DCallee(); printf("MastC Exiting.\n"); return 0; } ``` Where the compilation is run from the batch file: ``` Rem Compile, link and run batch file. IF EXIST .\DCallee.exe del .\DCallee.exe IF EXIST .\DCallee.map del .\DCallee.map IF EXIST .\DCallee.obj del .\DCallee.obj IF EXIST .\MastC.exe del .\MastC.exe IF EXIST .\MastC.map del .\MastC.map IF EXIST .\MastC.obj del .\MastC.obj dmd -m32omf -betterC -c DCallee.d dmc MastC.c DCallee.obj MastC.exe Rem Exited compile, link and run batch file. ``` Then everything runs properly. As an aside, it was a surprise to me to discover that the order of the file names in the dmc line was significant, bearing in mind MastC.c contains a 'main' function, and DCallee.d does not. As a further aside, I do recall the installer loading Visual Studio, but it didn't seem to help.
Re: ImportC issue?
On Wednesday, 19 April 2023 at 12:09:44 UTC, Richard (Rikki) Andrew Cattermole wrote: On 20/04/2023 12:07 AM, DLearner wrote: Error: C preprocess command sppn.exe failed for file ex01.c, exit status 1 Did you verify that sppn is accessible in that shell? As in run it, can it be found? If not its just a PATH variable issue. SPPN.exe not visible from that command prompt, but neither (using File Explorer) anywhere on the C: drive (lots of SPPNP.DLL's, in various Windows locations). If SPPN.exe essential to a component of DMD, was it not downloaded with it (and PATH modified to point to it), by the installer?
Re: ImportC issue?
On Wednesday, 19 April 2023 at 11:50:28 UTC, bachmeier wrote: [...] Did you use the switch `-m32omf`? https://dlang.org/spec/importc.html#auto-cpp No so following the references I tried every preprocessor option I could find: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c -m32omf failed launching sppn.exe ex01.c -HIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h -ED -oex01.i Error: C preprocess command sppn.exe failed for file ex01.c, exit status 1 C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c -c -m32omf failed launching sppn.exe ex01.c -HIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h -ED -oex01.i Error: C preprocess command sppn.exe failed for file ex01.c, exit status 1 C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c -c -m32mscoff failed launching cl.exe /P /Zc:preprocessor /PD /nologo ex01.c /FIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h /Fiex01.i Error: C preprocess command cl.exe failed for file ex01.c, exit status 1 C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c -c -m64 failed launching cl.exe /P /Zc:preprocessor /PD /nologo ex01.c /FIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h /Fiex01.i Error: C preprocess command cl.exe failed for file ex01.c, exit status 1 ``` Unfortunately all options failed.
ImportC issue?
C source ex01.c: ``` #include int main() { printf("hello world\n"); return 0; } ``` 'dmc ex01.c' produces message: ``` link ex01,,,user32+kernel32/noi; ``` but does generate .obj, .map and .exe files, and the exe executes properly. However, trying to use ImportC via 'dmd ex01.c' produces messages: ``` failed launching cl.exe /P /Zc:preprocessor /PD /nologo ex01.c /FIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h /Fiex01.i Error: C preprocess command cl.exe failed for file ex01.c, exit status 1 ``` This behaviour was repeated after a complete fresh re-installation of dmd & dmc from the website.
Re: Linking external functions?
On Tuesday, 18 April 2023 at 21:31:21 UTC, thinkunix wrote: [...] If not calling C code, why use extern(C) for D code? Wanted to test out options of calling D routine (possibly -betterC) from both C and (full) D.
Re: Linking external functions?
On Tuesday, 18 April 2023 at 20:00:18 UTC, ag0aep6g wrote: On Tuesday, 18 April 2023 at 19:49:04 UTC, DLearner wrote: ``` void main() { import std.stdio; extern(C) void ExtCallee(); ``` Move that declaration out of main. Thanks - worked! Is the declaration inside main not visible to the linker?
Linking external functions?
Wanted to try out linking two source files independantly compiled. ExtCallee.d source file: ``` extern(C) void ExtCallee() { import std.stdio; writeln("Entered: ", __FUNCTION__); writeln("Exiting: ", __FUNCTION__); } ``` ExtMain.d source file: ``` void main() { import std.stdio; extern(C) void ExtCallee(); writeln("Entered: ", __FUNCTION__); ExtCallee(); writeln("Exiting: ", __FUNCTION__); } ``` Then: ``` dmd ExtCallee -c ``` which worked, producing .obj file. However: ``` dmd ExtCallee.obj -run ExtMain lld-link: error: undefined symbol: __D7ExtMain4mainFZ9ExtCalleeUZv referenced by ExtMain.obj:(__Dmain) Error: linker exited with status 1 ``` Ideas?
Variable length arrays under -betterC?
Requirement is to write some D code (which avoids the GC), that will be called from C. So simple approach seemed to be to write D code under -betterC restrictions. However, also need variable length arrays - but D Dynamic Arrays not allowed under -betterC. So tried trivial example using std.container: ``` extern(C) void main() { import std.container; auto arr = Array!int(0, 2, 3); } ``` compiled with: ``` dmd -betterC -run Array_ex_01v00 ``` Which failed with: ``` C:\D\dmd2\windows\bin\..\..\src\druntime\import\core\internal\array\construction.d(207): Error: cannot use try-catch statements with -betterC C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(151): Error: template instance `core.internal.array.construction._d_arraysetctor!(const(Array!int)[], const(Array!int))` error instantiating C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(244): instantiated from here: `RangeT!(const(Array!int))` C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(633): instantiated from here: `RangeT!(Array!int)` Array_ex_01v00.d(5):instantiated from here: `Array!int` C:\D\dmd2\windows\bin\..\..\src\druntime\import\core\internal\array\construction.d(207): Error: cannot use try-catch statements with -betterC C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(151): Error: template instance `core.internal.array.construction._d_arraysetctor!(immutable(Array!int)[], immutable(Array!int))` error instantiating C:\D\dmd2\windows\bin\..\..\src\phobos\std\container\array.d(639): instantiated from here: `RangeT!(immutable(Array!int))` Array_ex_01v00.d(5):instantiated from here: `Array!int` ``` Any ideas how to implement variable length arrays under -betterC?
'auto' keyword
Is it correct that this _single_ keyword is used to indicate _two_ quite different things: 1. As a shorthand to make the type of the variable being declared the same as the type on the right hand side of an initial assignment. Example: ```auto A = 5;``` makes A an int. 2. To indicate storage class of variable. Example: ```auto int A;``` (I guess) makes A have automatic storage, ie contents lost when control goes out of scope, unlike static. Best regards
foreach with assoc. array
Hi Please consider (1): ``` void main() { import std.stdio; int wk_Idx; int[2] IntArr; IntArr[0] = 1; IntArr[1] = 2; for (wk_Idx = 0; wk_Idx <= 1; wk_Idx = wk_Idx + 1) { writeln("wk_Idx = ", wk_Idx, " IntArr = ", IntArr[wk_Idx]); } } ``` Now consider (2), which is (1) via assoc. array: ``` void main() { import std.stdio; int wk_Idx; int[int] IntArr; IntArr[0] = 1; IntArr[1] = 2; for (wk_Idx = 0; wk_Idx <= 1; wk_Idx = wk_Idx + 1) { writeln("wk_Idx = ", wk_Idx, " IntArr = ", IntArr[wk_Idx]); } } ``` And finally (3) which is (2) via a foreach: ``` void main() { import std.stdio; int wk_Idx; int[int] IntArr; IntArr[0] = 1; IntArr[1] = 2; foreach (wk_Idx; IntArr.keys) { writeln("wk_Idx = ", wk_Idx, " IntArr = ", IntArr[wk_Idx]); } } ``` (1) & (2) compile and run with the expected results. But (3) fails with: ``` Error: variable `wk_Idx` is shadowing variable `for3.main.wk_Idx` ``` Why is this usage wrong?
Re: Problem with ImportC example?
On Wednesday, 18 January 2023 at 14:18:58 UTC, Salih Dincer wrote: On Wednesday, 18 January 2023 at 13:45:04 UTC, DLearner wrote: On Tuesday, 17 January 2023 at 22:11:46 UTC, Ali Çehreli wrote: [...] dmd relies on system compiler programs for its ImportC feature. cl.exe seems to be the compiler. I think it is the compiler. Can you run that program from the command line? Fails with: ``` C:\Users\SoftDev>c1.exe 'c1.exe' is not recognized as an internal or external command, operable program or batch file. ``` You will run the cl.exe, not the c1.exe (be written with the letter l) SDB@79 Unfortunately, neither works: ``` C:\Users\SoftDev>cl.exe 'cl.exe' is not recognized as an internal or external command, operable program or batch file. C:\Users\SoftDev>c1.exe 'c1.exe' is not recognized as an internal or external command, operable program or batch file. ```
Re: Problem with ImportC example?
On Tuesday, 17 January 2023 at 22:11:46 UTC, Ali Çehreli wrote: [...] dmd relies on system compiler programs for its ImportC feature. cl.exe seems to be the compiler. I think it is the compiler. Can you run that program from the command line? Fails with: ``` C:\Users\SoftDev>c1.exe 'c1.exe' is not recognized as an internal or external command, operable program or batch file. ```
Re: Problem with ImportC example?
On Tuesday, 17 January 2023 at 19:17:31 UTC, DLearner wrote: On Tuesday, 17 January 2023 at 17:36:41 UTC, ryuukk_ wrote: On Tuesday, 17 January 2023 at 17:12:49 UTC, DLearner wrote: On Tuesday, 17 January 2023 at 15:55:40 UTC, bachmeier wrote: [...] Downloaded latest dmd for windows from website: ``` C:\Users\SoftDev>dmd --version DMD32 D Compiler v2.101.2-dirty Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved written by Walter Bright ``` But trial still failed: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c failed launching cl.exe /P /Zc:preprocessor /PD /nologo ex01.c /FIC:\D\dmd2\windows\bin\..\..\src\druntime\import\importc.h /Fiex01.i Error: C preprocess command cl.exe failed for file ex01.c, exit status 1 ``` It works for me ``` C:\Users\ryuukk\tmp>dmd -run ex01.c hello world ``` Double check your visual studio installation, something is wrong with your install probably Tried twice - same result. But VS installation is itself (IMO) not particularly intuitive. Would it be possible either to cite known working VS installation options on DLang website, or produce Windows installation script that takes such options automatically? FWIW, now tried a few standard D programs, work fine. Suggesting VS is not the problem?
Re: Problem with ImportC example?
On Tuesday, 17 January 2023 at 17:36:41 UTC, ryuukk_ wrote: On Tuesday, 17 January 2023 at 17:12:49 UTC, DLearner wrote: On Tuesday, 17 January 2023 at 15:55:40 UTC, bachmeier wrote: On Tuesday, 17 January 2023 at 13:21:37 UTC, DLearner wrote: On Tuesday, 17 January 2023 at 11:21:08 UTC, Dennis wrote: On Tuesday, 17 January 2023 at 11:16:25 UTC, DLearner wrote: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c ex01.c(1): Error: C preprocessor directive `#include` is not supported ex01.c(1): Error: no type for declarator before `#` ex01.c(5): Error: no type for declarator before `return` ex01.c(6): Error: no type for declarator before `}` ``` What is your `dmd --version`? I suspect you have a version where you still have to manually pre-process the .c file, instead of a more recent version which invokes the pre-processor itself. ``` C:\Users\SoftDev>dmd --version DMD32 D Compiler v2.100.2-dirty Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved written by Walter Bright ``` You may want to use the nightly build if you're working with ImportC: https://github.com/dlang/dmd/releases/tag/nightly They're doing a lot of work with it. Downloaded latest dmd for windows from website: ``` C:\Users\SoftDev>dmd --version DMD32 D Compiler v2.101.2-dirty Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved written by Walter Bright ``` But trial still failed: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c failed launching cl.exe /P /Zc:preprocessor /PD /nologo ex01.c /FIC:\D\dmd2\windows\bin\..\..\src\druntime\import\importc.h /Fiex01.i Error: C preprocess command cl.exe failed for file ex01.c, exit status 1 ``` It works for me ``` C:\Users\ryuukk\tmp>dmd -run ex01.c hello world ``` Double check your visual studio installation, something is wrong with your install probably Tried twice - same result. But VS installation is itself (IMO) not particularly intuitive. Would it be possible either to cite known working VS installation options on DLang website, or produce Windows installation script that takes such options automatically?
Re: Problem with ImportC example?
On Tuesday, 17 January 2023 at 15:55:40 UTC, bachmeier wrote: On Tuesday, 17 January 2023 at 13:21:37 UTC, DLearner wrote: On Tuesday, 17 January 2023 at 11:21:08 UTC, Dennis wrote: On Tuesday, 17 January 2023 at 11:16:25 UTC, DLearner wrote: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c ex01.c(1): Error: C preprocessor directive `#include` is not supported ex01.c(1): Error: no type for declarator before `#` ex01.c(5): Error: no type for declarator before `return` ex01.c(6): Error: no type for declarator before `}` ``` What is your `dmd --version`? I suspect you have a version where you still have to manually pre-process the .c file, instead of a more recent version which invokes the pre-processor itself. ``` C:\Users\SoftDev>dmd --version DMD32 D Compiler v2.100.2-dirty Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved written by Walter Bright ``` You may want to use the nightly build if you're working with ImportC: https://github.com/dlang/dmd/releases/tag/nightly They're doing a lot of work with it. Downloaded latest dmd for windows from website: ``` C:\Users\SoftDev>dmd --version DMD32 D Compiler v2.101.2-dirty Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved written by Walter Bright ``` But trial still failed: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c failed launching cl.exe /P /Zc:preprocessor /PD /nologo ex01.c /FIC:\D\dmd2\windows\bin\..\..\src\druntime\import\importc.h /Fiex01.i Error: C preprocess command cl.exe failed for file ex01.c, exit status 1 ```
Re: Problem with ImportC example?
On Tuesday, 17 January 2023 at 11:21:08 UTC, Dennis wrote: On Tuesday, 17 January 2023 at 11:16:25 UTC, DLearner wrote: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c ex01.c(1): Error: C preprocessor directive `#include` is not supported ex01.c(1): Error: no type for declarator before `#` ex01.c(5): Error: no type for declarator before `return` ex01.c(6): Error: no type for declarator before `}` ``` What is your `dmd --version`? I suspect you have a version where you still have to manually pre-process the .c file, instead of a more recent version which invokes the pre-processor itself. ``` C:\Users\SoftDev>dmd --version DMD32 D Compiler v2.100.2-dirty Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved written by Walter Bright ```
Problem with ImportC example?
This relates to the first example under 41.1 Quick Examples. Stored as ex01.c, run as shown. ``` #include int main() { printf("hello world\n"); return 0; } ``` Produced: ``` C:\Users\SoftDev\Documents\BDM\D\ImportC>dmd ex01.c ex01.c(1): Error: C preprocessor directive `#include` is not supported ex01.c(1): Error: no type for declarator before `#` ex01.c(5): Error: no type for declarator before `return` ex01.c(6): Error: no type for declarator before `}` ```
Unittests on a module
If unittest run without a main() being present, crashes on link error: ``` lld-link: error: subsystem must be defined Error: linker exited with status 1 ``` Is this intended? It's not a problem to add temporary ``` void main() { } ``` to the bottom of the module, but seems wrong as not then testing _exactly_ what is to be imported elsewhere.
Re: BetterC unexpected results
On Sunday, 8 January 2023 at 23:59:21 UTC, ryuukk_ wrote: [...] Example_03: ``` void main() { import core.stdc.stdio : printf; int[] A; printf("Hello betterC\n"); } ``` ``` dmd -betterC -run Example_03 ``` Expected result: Failure at compilation stage, owing to presence of dynamic array A, when -betterC set. Actual result: Failed at link (not compilation) stage. That example is working for me What's the exact code you wrote? ``` void main() { import core.stdc.stdio : printf; int[] A; printf("Hello betterC\n"); } ``` Result: ``` C:\Users\SoftDev\Documents\BDM\D\BetterC>dmd -betterC -run Example_03 lld-link: error: undefined symbol: __d_run_main referenced by Example_03.obj:(_main) Error: linker exited with status 1 ``` Compiler version: ``` C:\Users\SoftDev\Documents\BDM\D\BetterC>dmd --version DMD32 D Compiler v2.100.2-dirty ```
BetterC unexpected results
I thought dynamic arrays were unavailable under -betterC. Example_02: ``` extern(C) void main() { import core.stdc.stdio : printf; int[] A; printf("Hello betterC\n"); } ``` ``` dmd -betterC -run Example_02 ``` Expected result: Failure at compilation stage, owing to presence of dynamic array A, when -betterC set. Actual result: Ran to completion, dislaying the message. Example_03: ``` void main() { import core.stdc.stdio : printf; int[] A; printf("Hello betterC\n"); } ``` ``` dmd -betterC -run Example_03 ``` Expected result: Failure at compilation stage, owing to presence of dynamic array A, when -betterC set. Actual result: Failed at link (not compilation) stage.
Re: GC interaction with malloc/free
On Thursday, 5 January 2023 at 19:54:01 UTC, H. S. Teoh wrote: On Thu, Jan 05, 2023 at 07:49:38PM +, DLearner via Digitalmars-d-learn wrote: Suppose there is a D main program (not marked anywhere with @nogc), that _both_ A: Calls one or more C functions that themselves call malloc/free; and also B: Calls one or more D functions that themselves call malloc/free via `import core.stdc.stdlib;` Assuming the malloc/free's are used correctly, does this situation risk crashing the D main program? [...] core.stdc.stdlib.{malloc,free} *is* the exact same malloc/free that C uses, it has nothing to do with the GC. The allocated memory is taken from the malloc/free part of the heap, which is disjoint from the heap memory managed by the GC. So, it should not cause any crashes. T That's comforting, but there is a reference in: https://dlang.org/blog/2017/09/25/go-your-own-way-part-two-the-heap/ '...Given that it’s rarely recommended to disable the GC entirely, most D programs allocating outside the GC heap will likely also be using memory from the GC heap in the same program. In order for the GC to properly do its job, it needs to be informed of any non-GC memory that contains, or may potentially contain, references to memory from the GC heap.' Followed by things that have to be done (GC.addRange) to avoid interaction effects?
GC interaction with malloc/free
Suppose there is a D main program (not marked anywhere with @nogc), that _both_ A: Calls one or more C functions that themselves call malloc/free; and also B: Calls one or more D functions that themselves call malloc/free via `import core.stdc.stdlib;` Assuming the malloc/free's are used correctly, does this situation risk crashing the D main program? Best regards
Re: Thinking about the difference between fixed and 'dynamic' arrays.
On Wednesday, 30 November 2022 at 02:29:03 UTC, Paul Backus wrote: [...] If you want a dynamic array with value semantics, you should use a library-defined container type (e.g., `struct DynamicArray`). I agree should not change existing meaning of ``` int[] A; ``` But why not allow a construct for value-type variable arrays like: ``` int[*] B; ``` Best regards
Re: Thinking about the difference between fixed and 'dynamic' arrays.
On Tuesday, 29 November 2022 at 19:06:20 UTC, rikki cattermole wrote: [...] Please see the following example: ``` void main() { import std.stdio; int[] VarArr1, VarArr2; VarArr1.length = 6; VarArr1[5] = 10; VarArr1[4] = 9; VarArr1[3] = 8; VarArr1[2] = 7; VarArr1[1] = 6; VarArr1[0] = 5; VarArr2 = VarArr1; writeln("VarArr1 = ", VarArr1); writeln("VarArr2 = ", VarArr2); VarArr1[3] = 40; writeln("VarArr1 = ", VarArr1); writeln("VarArr2 = ", VarArr2); return; } ``` And it's result: ``` VarArr1 = [5, 6, 7, 8, 9, 10] VarArr2 = [5, 6, 7, 8, 9, 10] VarArr1 = [5, 6, 7, 40, 9, 10] VarArr2 = [5, 6, 7, 40, 9, 10] ``` Many languages have fixed-length arrays, D's such construct works as someone approaching the language would expect. Many languages also have variable length arrays, I suggest D's 'dynamic array' _does not_ operate as expected. I'm not suggesting that the result contradicts D's definition of 'dynamic array', nor it's implementation, just that 'dynamic array' is not a reasonable description for a construct that behaves like VarArr2[3] becoming 40.
Thinking about the difference between fixed and 'dynamic' arrays.
To me, it appears that there are really two (_entirely separate_) concepts: A. Supporting the useful concept of variable length (but otherwise entirely conventional) arrays; B. Supporting a language feature that acts as a window to an array, through which that array can be manipulated. And currently these two concepts are combined. Suggestion: it would be clearer if the two concepts were separated: 1. Convert 'int[] VarArr;' so it produces a straightforward _value-type_ variable array, called 'VarArr'; 2. Implement a new concept 'int slice Window;' to produce an object of type 'int slice', called 'Window'. 'Window' is a 'slice' into an int array, not an array itself or even a variable. Opinions?
Re: Comparison of two 'dynamic arrays'.
On Sunday, 13 November 2022 at 16:11:17 UTC, matheus. wrote: [...] You should add the code below after "auto B = A.dup;": B[0].Txt = A[0].Txt.dup; The "Txt" property inside B is still referencing A without the above. Matheus. Thank you - your suggestion worked. The slight generalisation shown at bottom also worked. However, is there a way of avoiding the for-loop? Things like ``` B[].Txt = A[].Txt.dup; ``` did not work for me. ``` void main() { import std.stdio; int index; struct test_struct { char[] Txt; } test_struct[] A; A.length = 2; A[0].Txt.length = 1; A[1].Txt.length = 1; A[0].Txt[0] = 'W'; A[1].Txt[0] = 'X'; writeln(A); auto B = A.dup; for (index = 0; index < A.length; index = index + 1) { B[index].Txt = A[index].Txt.dup; } writeln(A, B); A[0].Txt[0] = 'Y'; A[1].Txt[0] = 'Z'; writeln(A, B); } ```
Re: Comparison of two 'dynamic arrays'.
On Sunday, 13 November 2022 at 14:39:26 UTC, Siarhei Siamashka wrote: On Sunday, 13 November 2022 at 14:28:45 UTC, DLearner wrote: Creating a step 1.5: ``` int[] B = A; ``` ```D auto B = A.dup; ``` This will create a copy of A rather than referencing to the same buffer in memory. Tested: ``` void main() { import std.stdio; struct test_struct { char[] Txt; } test_struct[] A; A.length = 1; A[0].Txt.length = 1; A[0].Txt[0] = 'X'; writeln(A); auto B = A.dup; writeln(A, B); A[0].Txt[0] = 'Y'; writeln(A, B); } ``` Got: ``` [test_struct("X")] [test_struct("X")][test_struct("X")] [test_struct("Y")][test_struct("Y")] ``` Expected last line to be Y,X not Y,Y.
Comparison of two 'dynamic arrays'.
Hi Program has two steps: 1. Creates an array (int[] A), whose size and element values are only known at run-time. Then: 2. The elements (but not the array size) are further processed in a way that may or may not alter their value. Requirement: to identify the indices (if any) of the elements whose value changed in step 2. What is the recommended way to do this? Creating a step 1.5: ``` int[] B = A; ``` And then step 2.5: ``` for (int j=0, j < A.length, j = j+1) { if (B[j] != A[J]) { < write the j value away somewhere> } else { } } ``` Won't work, as any step 2 changes to A will be reflected in B. In passing,is 'dynamic array' a good title for a structure/concept that seems more of a 'view'? Surely 'dynamic array' is best used for something that is (no more than) a static array whose dimensions can vary at run time? Best regards
Re: Importing modules under DUB on Windows
On Friday, 28 October 2022 at 21:32:46 UTC, rikki cattermole wrote: On 29/10/2022 4:15 AM, DLearner wrote: However, going forward, I don't want copies of OM anywhere other than UD. If you want your own private library on your system (that will get used a lot), you can create a package and use ``$ dub add-local .`` to add it to the available packages for lookup, without needing a version control system. Then you just add it as a dependency on an as needed basis (use ``*`` for version should work fine). In the end, downloaded terminal.d from GitHub, stored in directory UD. Then within 'source' directory, following Adam D Ruppe above, `dmd -i -IC:\...\UD\ -run app` And it just worked. No calculating relative paths, no remembering to double `\`. I think DUB is a little too sophisticated for my needs.
Re: Importing modules under DUB on Windows
On Friday, 28 October 2022 at 11:35:44 UTC, Adam D Ruppe wrote: On Wednesday, 26 October 2022 at 16:20:01 UTC, DLearner wrote: Wanted to use a function stored in a module outside the main source. easiest thing to do with dub is to add it as a sourcePath or a sourceFile. Well, actually, easiest is to just copy the module right into your default src folder, but second easiest is to add the other thing as the sourcePath/sourceFile. Messing with lib compiles and import paths rarely worth the hassle. (and without dub btw you can make a generic lib directory, add it to your -I path, then just `dmd -I/path/to/libs -i yourmainfile.d` and it automatically picks up things from import paths. that's how i do it myself) Also later i see you are using the arsd terminal.d, which you can also use through dub's dependency system by adding `arsd-official:terminal` to its list. Hi To avoid confusion: I wanted to use (yours I think!) arsd-official:terminal, and a (near-trivial) function (call it NTF) held inside one of my own modules (call it OM), itself inside my utilities directory (call it UD). ` "dependencies": { "arsd-official:terminal": "~>10.9.4" }, ` was set in the JSON file. When I copied OM to the package 'source' directory, `dub run` executed, nothing blew up, and the whole thing went as expected. However, going forward, I don't want copies of OM anywhere other than UD. Doing that potentially leaves similar but non-identical copies of software around, causing problems at a later stage. So I delected OM from the 'source' directory, and (following suggestions given earlier) reviewed my calculation of the _relative_ path from the package directory to UD, and put the result into `sourcePaths`. `dub run` then seemed to find OM and the NTF inside it, as got through compile to: `Target is a library. Skipping execution.` Google then gave the suggestion: `"targetType": "executable",` Took suggestion, dub run then produced: `Linking... lld-link: error: subsystem must be defined Error: linker exited with status 1` Any further suggestions gratefully received. Comments: I am conscious that when OM was in the 'source' directory (with app), everything 'just worked'. Therefore, to me, if OM is somewhere else, but I provide that location to dub, everything should work exactly as before. But that does not happen. I also thought it strange that I had to provide the UD location as a relative rather than absolute path. Best regards
Re: Importing modules under DUB on Windows
On Thursday, 27 October 2022 at 00:35:26 UTC, Hipreme wrote: On Wednesday, 26 October 2022 at 22:51:53 UTC, DLearner wrote: On Wednesday, 26 October 2022 at 18:53:58 UTC, Hipreme wrote: On Wednesday, 26 October 2022 at 18:37:00 UTC, DLearner wrote: [...] The linker failed to resolve because it didn't include the symbols you imported. Think of import a way to the compiler resolve the compilation. Think of source a way to both the compiler and the linker to resolve compilation and linking. If you give only the import path, you will need a library. What you actually want is to put your new importPath to the JSON array `sourcePaths` Added `"sourcePaths": [ "C\\Users\\..." ]` Unfortunately failed with `core.exception.AssertError@source\dub\internal\vibecompat\inet\path.d(222): Trying to append absolute path.` I tried to construct a relative path to the module directory from the project directory, that didn't work either. Okay. So this error is very strange, the other thing I can give you advice is: If your other thing is another dub project, you can add it as a dependency by putting in your dub.json ```json "dependencies" : { "your_project_name" : {"path" : "your/path/here"} } ``` AFAIK, there is no problem in putting an absolute path dependency, in fact, I'm using things from another drive letter. Hi I'm not getting on with DUB. Maybe fewer people use it under Windows, so Windows constructs don't get exercised so much. Is there a non-DUB way of arranging that `import arsd.terminal;` will use that module as held on GitHub? (DUB name: "arsd-official:terminal": "~>10.9.4"). OS: Windows 10. Compiler: DMD. Best regards
Re: Importing modules under DUB on Windows
On Wednesday, 26 October 2022 at 18:53:58 UTC, Hipreme wrote: On Wednesday, 26 October 2022 at 18:37:00 UTC, DLearner wrote: On Wednesday, 26 October 2022 at 16:58:08 UTC, H. S. Teoh wrote: On Wed, Oct 26, 2022 at 04:20:01PM +, DLearner via Digitalmars-d-learn wrote: [...] Maybe try instead: "importPaths": [ "C:\\Users\\..." ] since the error message indicates that it expects an array, not a string. T Thanks for this. Following your suggestion, seems that DUB found the module (as it got through to the linking step without complaint), but then the linker failed to resolve the function name. However, when I moved the module to the project `'source'` directory (and took out the `importPaths` JSON entry), everything worked. But I don't really want to do this - the module is my collection of utilities, used in a variety of projects, so doesn't really belong within one specific project. Best regards The linker failed to resolve because it didn't include the symbols you imported. Think of import a way to the compiler resolve the compilation. Think of source a way to both the compiler and the linker to resolve compilation and linking. If you give only the import path, you will need a library. What you actually want is to put your new importPath to the JSON array `sourcePaths` Added `"sourcePaths": [ "C\\Users\\..." ]` Unfortunately failed with `core.exception.AssertError@source\dub\internal\vibecompat\inet\path.d(222): Trying to append absolute path.` I tried to construct a relative path to the module directory from the project directory, that didn't work either.
Re: Importing modules under DUB on Windows
On Wednesday, 26 October 2022 at 16:58:08 UTC, H. S. Teoh wrote: On Wed, Oct 26, 2022 at 04:20:01PM +, DLearner via Digitalmars-d-learn wrote: Hi Never used DUB before. Wanted to use a function stored in a module outside the main source. Main source has `import ;` Put a line into the JSON: `"importPaths": "C:\\Users\\..."` pointing to the directory holding the module. `dub run` failed with `Expected JSON array, got string`. Maybe try instead: "importPaths": [ "C:\\Users\\..." ] since the error message indicates that it expects an array, not a string. T Thanks for this. Following your suggestion, seems that DUB found the module (as it got through to the linking step without complaint), but then the linker failed to resolve the function name. However, when I moved the module to the project `'source'` directory (and took out the `importPaths` JSON entry), everything worked. But I don't really want to do this - the module is my collection of utilities, used in a variety of projects, so doesn't really belong within one specific project. Best regards
Re: Obtaining type and value of a variable named in another variable
On Saturday, 16 October 2021 at 19:29:59 UTC, Dennis wrote: On Saturday, 16 October 2021 at 19:28:04 UTC, DLearner wrote: How does one obtain from strVar: 1. The type of fooVar; `typeof(mixin(strVar))` 2. The value of fooVar? `mixin(strVar)` ``` void main() { import std.stdio; int fooVar = 4; string strVar; strVar = "fooVar"; writeln(typeof(mixin(strVar))); writeln(mixin(strVar)); } ``` Failed with 2x "Error: variable `strVar` cannot be read at compile time".
Obtaining type and value of a variable named in another variable
Hi Suppose string variable strVar has value "fooVar". fooVar is a valid variable name used elsewhere in the program. How does one obtain from strVar: 1. The type of fooVar; 2. The value of fooVar? Best regards
Re: uint overflow behaviour
Thanks for the responses.
uint overflow behaviour
Please confirm that if the addition of two uint variables produces a result larger than can be held in a uint: 1. This is a D-legal operation (however inadvisable!), with the D-defined result of wraparound; 2. Emphasing 1. above: the result is not undefined, or an error (by the rules of D), or simply implementation-dependant (whether by compiler or chip). Best regards
Re: Run-time setting of immutable variable?
On Thursday, 2 September 2021 at 23:12:28 UTC, Steven Schveighoffer wrote: [...] immutable means "I can never change and *everything I point at* can never change". [...] If that is how the language defines the keyword 'immutable' when used in the definition of a pointer variable, then so be it. I would, however, suggest that the additional 'action-at-a-distance' implication (freezing not just the variable itself, but also it's target) is inconsistent with the definition of 'immutable' with other variable types. Surely it would be better to reserve 'immutable' on a pointer to mean simply set-once on the pointer itself (with no implications for whatever the pointer is pointing to), and another keyword ('blocked'?) for the current definition?
Re: Run-time setting of immutable variable?
On Thursday, 2 September 2021 at 16:46:46 UTC, Steven Schveighoffer wrote: On 9/2/21 12:01 PM, DLearner wrote: Suppose there is a variable that is set once per run, and is (supposed) never to be altered again. However, the value to which it is set is not known at compile time. Example below, variable is 'ArrPtr'; ``` ubyte[10] Arr; // immutable void* ArrPtr; void* ArrPtr; void main() { ArrPtr = cast(void*)Arr[0]; // modify ArrPtr> } ``` Is there a way of getting D to guarantee that ArrPtr is never modified after ``` ArrPtr = cast(void*)Arr[0]; ```] You shouldn't be doing this. `Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's immutable. If you want to guarantee that `ArrPtr` never changes once set, yet still want it to point at mutable data, you need to use a type that does that (like a head mutable or "write once" type), which I believe doesn't exist in phobos. If you don't actually need to mutate the data via `ArrPtr`, you can make it const, and use H.S. Teoh's solution. But you should not use immutable, as the compiler implies that data pointed at is also immutable (and of course, you won't need casting). Make sure you use regular `static this`, not `shared static this`, as your fields are thread-local, not shared. -Steve The following clean-compiled and produced the expected result: ``` ubyte[10] Arr; immutable void* ArrPtr; shared static this() { ArrPtr = cast(immutable void*)(&Arr[0]); } void main() { import std.stdio; void* ArrPtr2; ArrPtr2 = cast(void*)(&Arr[0]); writeln("ArrPtr = ", ArrPtr); writeln("ArrPtr2 = ", ArrPtr2); // consistency test // ArrPtr = ArrPtr + 1; // mutability test - compile (correctly) failed when uncommented. ArrPtr2 = ArrPtr2 + 1; Arr[1] = 4; Arr[1] = 7; // mutability test } ``` The following produced deprecated warnings, but still seemed to work: ``` ubyte[10] Arr; immutable void* ArrPtr; static this() { ArrPtr = cast(immutable void*)(&Arr[0]); } void main() { import std.stdio; void* ArrPtr2; ArrPtr2 = cast(void*)(&Arr[0]); writeln("ArrPtr = ", ArrPtr); writeln("ArrPtr2 = ", ArrPtr2); // consistency test // ArrPtr = ArrPtr + 1; // mutability test on ArrPtr - compile (correctly) failed when uncommented. ArrPtr2 = ArrPtr2 + 1; Arr[1] = 4; Arr[1] = 7; // mutability test on Arr } ``` I am looking for a mutable Arr but would like an immutable ArrPtr. ``` `Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's immutable. ``` Surely there is no inconsistency - at run time the array is in a fixed place, so ArrPtr is (or at least should be) a constant, but the contents of the array can vary as the program runs.
Run-time setting of immutable variable?
Suppose there is a variable that is set once per run, and is (supposed) never to be altered again. However, the value to which it is set is not known at compile time. Example below, variable is 'ArrPtr'; ``` ubyte[10] Arr; // immutable void* ArrPtr; void* ArrPtr; void main() { ArrPtr = cast(void*)Arr[0]; // ArrPtr> } ``` Is there a way of getting D to guarantee that ArrPtr is never modified after ``` ArrPtr = cast(void*)Arr[0]; ``` Best regards
Re: Scope of Mixins
On Thursday, 26 August 2021 at 16:28:22 UTC, Adam D Ruppe wrote: On Thursday, 26 August 2021 at 16:16:55 UTC, DLearner wrote: Please confirm that mixins of format: You really shouldn't use string mixins like this at all. If you want to work with a variable, pass the variable itself as an argument to the function and use it with regular code instead of passing names as strings. void do_something(alias v)() { // use v like a normal variable } int a; do_someting!a; // pass the variable a as an alias so you can use it inside Thank you for your suggestion. For the record, the code below behaves as expected. ``` void main() { int VarInt; int* VarIntPtr; double VarDbl; do_something!VarInt; do_something!VarIntPtr; do_something!VarDbl; } void do_something(alias v)() { import std.stdio; if (typeof(v).stringof == "int" ) { writeln("int var detected"); } else if (typeof(v).stringof == "int*") { writeln("int* var detected"); } else { writeln("Unrecognised type"); } } ```
Re: Scope of Mixins
On Thursday, 26 August 2021 at 16:28:22 UTC, Adam D Ruppe wrote: On Thursday, 26 August 2021 at 16:16:55 UTC, DLearner wrote: Please confirm that mixins of format: You really shouldn't use string mixins like this at all. If you want to work with a variable, pass the variable itself as an argument to the function and use it with regular code instead of passing names as strings. void do_something(alias v)() { // use v like a normal variable } int a; do_someting!a; // pass the variable a as an alias so you can use it inside The object was to take a variable, and do alternative things with it depending on (say) whether it was an 'int' or an 'int*'. Since entirely possible (indeed likely) that operations on 'int' invalid or meaningless with 'int*', to me seemed better to find a way that at _compile-time_ detected the difference, and only generated code valid for the type used. Originally, there were mixins that only coped with each type. These work, but a chore to update mixin name as variable type changed. So idea is just one mixin which can compile-time detect variable type and generate appropriate code. Got it to work, except for this scoping issue...
Scope of Mixins
Please confirm that mixins of format: ``` string mxn1(string VarName) { ... } ``` Invoked like: ``` mixin(mxn1("Var1")); ``` Have a wider scope than mixins like: ``` string mxn2(string VarName)() { ... } ``` Invoked like: ``` mixin(mxn2!"Var2"); ``` I tried direct replacement of former by the latter, could not get clean compile until definition moved into same module. Best regards
Re: Mixin/static if issue
On Wednesday, 25 August 2021 at 22:57:23 UTC, jfondren wrote: Contrast: [...] ```d void main() { import std.stdio; uint TestVar = 5; string mxnWrite_Size_t(string VarName)() { static if (typeof(mixin(VarName)).stringof == "uint") { return `write("` ~ VarName ~ `");`; } else { return `writeln("Apparently TestVar not a uint");`; } } mixin(mxnWrite_Size_t!"TestVar"); } ``` Output: TestVar Confirm works for me. Thanks!
Re: Mixin/static if issue
On Wednesday, 25 August 2021 at 22:33:00 UTC, H. S. Teoh wrote: [...} I think what you meant to write is: static if (typeof(mixin(VarName)).stringof == "uint") { You want the type of the variable named by VarName, not the type of VarName. T I understand your reasoning, but: ``` void main() { import std.stdio; uint TestVar = 5; string mxnWrite_Size_t(string VarName) { static if (typeof(mixin(VarName)).stringof == "uint") { return `write("` ~ VarName ~ `");`; } else { return `writeln("Apparently TestVar not a uint");`; } } mixin(mxnWrite_Size_t("TestVar")); } ``` produced Error: variable `VarName` cannot be read at compile time
Mixin/static if issue
Please see below: ``` void main() { import std.stdio; uint TestVar = 5; string mxnWrite_Size_t(string VarName) { static if (typeof(VarName).stringof == "uint") { return `write("` ~ VarName ~ `");`; } else { return `writeln("Apparently TestVar not a uint");`; } } mixin(mxnWrite_Size_t("TestVar")); } ``` What I expected was the string "TestVar". What I got was the "Apparently..." error message. Please, why is this?
Unexpected result comparing to null
Hi The code below compiles and runs producing 'Not null'. ``` void main() { import std.stdio; int Var1; int* ptrVar; ptrVar = &Var1; if (ptrVar == null) { writeln("Null"); } else { writeln("Not null"); } } ``` However, should it not fail to compile, as '==' used instead of 'is'? Best regards
DMD compiler - warning of unused variables
Hi Please see code below: ``` void main() { import std.stdio; size_t i; size_t j; i = 5; writeln("i = ",i); } ``` Is there a compiler option that would warn that variable 'j' is defined but not used? Best regards
Routing of AssertError messages
Hi This may be due to Windows, not DMD. Please see code below (held in test.d): ``` void main() { import std.stdio; writeln("Test"); assert(false, "TestAssert"); } ``` ` dmd -i -run test.d ` results in both "Test" and the "TestAssert" string (and trace) being routed to screen. But ` dmd -i -run test.d > op.txt ` results in only "Test" going into op.txt, the "TestAssert" string (and trace) being routed to screen as before. I expected both "Test" and the "TestAssert" string (and trace) to go into op.txt. The idea was to use op.txt as documentation of a successful test of the "TestAssert" string. Best regards
Re: Scope of enum
On Sunday, 11 July 2021 at 12:47:48 UTC, Adam D Ruppe wrote: On Sunday, 11 July 2021 at 12:37:20 UTC, DLearner wrote: C:\Users\SoftDev\Documents\BDM\D\Examples\CTFE\T2>type k_mod.d // k_mod.d ubyte[MemSiz] MemPool; You didn't import the other module here. D's imports aren't like C's includes. Each module is independent and can only see what it itself imports. A module has no idea who is importing it. It only knows what it imports inside itself. Adding the second import worked - thank you. But there is a point of principle: To me, doesn't really matter about what goes in `test01.d`, just test harness. But adding `import test01.d` to `k_mod.d` looks like 'mixing' the real code in `k_mod.d` with other code that is just for the support of the test harness. And that support would have to be changed for each test. Surely we want the target code, if possible, to be unchanged from test to test? Is there a 'D' way of avoiding the issue?
Re: Scope of enum
On Sunday, 11 July 2021 at 12:01:27 UTC, jfondren wrote: On Sunday, 11 July 2021 at 10:58:58 UTC, DLearner wrote: Is there a way of forcing DMD to extend the scope of `MemSiz` to include `k_mod`? Best regards ``` $ cat k_mod.d import test01; ubyte[MemSiz] MemPool; $ cat test01.d enum MemSiz = 240; void main() { import std.stdio, k_mod; writeln(typeid(MemPool)); } $ dmd test01.d k_mod.d $ ./test01 ubyte[240] ``` Doesn't seem to work for me (Windows): ``` C:\Users\SoftDev\Documents\BDM\D\Examples\CTFE\T2>type test01.d // test01.d enum MemSiz = 240; void main() { import k_mod; } C:\Users\SoftDev\Documents\BDM\D\Examples\CTFE\T2>type k_mod.d // k_mod.d ubyte[MemSiz] MemPool; C:\Users\SoftDev\Documents\BDM\D\Examples\CTFE\T2>dmd -i test01.d k_mod.d k_mod.d(4): Error: undefined identifier `MemSiz`` ```
Scope of enum
Please see the two code snippets below: ``` // test01.d enum MemSiz = 240; void main() { import k_mod; } ``` and ``` // k_mod.d ubyte[MemSiz] MemPool; ``` A number of tests need to be run on code in `k_mod`, with different sizes of the static array `MemPool` in each test. So each test has the enum `MemSiz`, but set to different values. However, DMD does not recognise the enum `MemSiz` within `k_mod`, failing with 'undefined identifier'. Is there a way of forcing DMD to extend the scope of `MemSiz` to include `k_mod`? Best regards
assert(false) and GC
Hi Please confirm that: ` assert(false, __FUNCTION__ ~ "This is an error message"); ` Will _not_ trigger GC issues, as the text is entirely known at compile time. Best regards
Re: Scope of import
On Saturday, 15 May 2021 at 11:38:22 UTC, Adam D. Ruppe wrote> Just use ``` dmd -i main.d instead. It will be about 2x faster and more reliable. ``` Your suggestion worked. Thank you.
Re: Scope of import
On Saturday, 15 May 2021 at 07:19:08 UTC, Mike Parker wrote: Then it must be an issue with rdmd... rdmd build 20210311 Running under Win-10.
Re: Scope of import
On Saturday, 15 May 2021 at 07:05:00 UTC, Mike Parker wrote: That's odd. What's your command line? rdmd main.d
Scope of import
``` // main void main() { import A; // import B; import std.stdio; writeln("Entered main"); fnA1(); writeln("Leaving main"); } ``` ``` module A; void fnA1() { import B; import std.stdio; writeln("Entered fnA1"); fnB1(); writeln("Leaving fnA1"); } ``` ``` module B; void fnB1() { import std.stdio; writeln("Entered fnB1"); writeln("Leaving fnB1"); } ``` 1. Code above compiles but fails on linker step with 'Error 42 Symbol Undefined'. To me, unexpected behaviour as imports arranged to pick up symbols (with minimum scope). 2. Uncommenting the 'import B' in main everything works correctly. To me, particularly unexpected behaviour as no symbol from B directly used in main (also undesirable to set scope unnecessarily wide). Best regards
Can rdmd (under Windows 10) use linker other than Optlink?
I am getting 'Error 42: Symbol Undefined' while testing some (fairly) complex imports. There was a reference in January to an Optlink bug that seemed like it could be responsible. If rdmd can use another linker (and one was recommended), I might be able to test things further. Best regards
Scope of 'alias'
>>> void foo(pint p1) { alias pint=uint; import std.stdio; writeln("p1 = ", p1); } void main() { alias pint=uint; pint var1; var1 = 7; foo(var1); } <<< Does not compile. But the rather similar: alias pint=uint; void foo(pint p1) { import std.stdio; writeln("p1 = ", p1); } void main() { pint var1; var1 = 7; foo(var1); } <<< Is fine. So 'alias' only valid from definition to end-of-function, rather than whole function? Best regards