Re: longjmp [still] crashes on windows?
SrMordred had already figured it (setjmp vs _setjmp(..., null)) out: https://forum.dlang.org/post/abrjmdvvlqdmmnpxc...@forum.dlang.org
longjmp [still] crashes on windows?
An old thread about the same problem: https://forum.dlang.org/thread/mmxwhdypncaeikknl...@forum.dlang.org struct jmp_buf { byte[256] data; } jmp_buf my_jmp_buf; extern(C) { int setjmp(ref jmp_buf env); void longjmp(ref jmp_buf env, int); } void second() { writefln("second"); // calling 'longjmp' results in a crash with '-m64' // it works with '-m32mscoff' longjmp(my_jmp_buf, 1); } void first() { second(); writefln("first"); } void main() { if (setjmp(my_jmp_buf)) { writefln("we longjmp-ed to here"); } else { first(); } } I also want to use '-betterC' (exceptions won't work).
Re: Why does using zlib without pragma(lib, ...) work?
What other libraries (if any) are part of Phobos?
Why does using zlib without pragma(lib, ...) work?
The following compiles without pragma(lib, ...): extern(C) { const(char)* zlibVersion(); } void main() { const(char)* sz = zlibVersion(); }
D's type declarations seem to read right to left.
D's type declarations seem to read right to left. int an_integer; int[10] an_array_of_10_integers; int[10]* a_pointer_to_an_array_of_10_integers = _array_of_10_integers; int*[10] an_array_of_10_pointers_to_integers; int*[10]* a_pointer_to_an_array_of_10_pointers_to_integers = _array_of_10_pointers_to_integers; int[3][2] an_array_of_2_arrays_of_3_integers; int[string] a_hashtable_with_string_keys_and_integer_values; int[3][string][2] an_array_of_2_hashtables_with_string_keys_and_array_of_3_integers_values; int function(float) a_pointer_to_a_function_that_takes_a_float_and_returns_an_integer; int function(float)[10] an_array_of_10_functions_that_take_floats_and_return_integers; I think this is a big improvement over C's "spiral" way of reading types: http://www.unixwiz.net/techtips/reading-cdecl.html I guess it could've been left to right, but... it's okay.
Re: How to use an associative array with array values.
I see. I guess the other would be: { int[8192] bar; int[8192][string] foo; foo["a"] = bar; foo["a"][8191] = -1; }
How to use an associative array with array values.
// foo is an associative array/hashtable with // key type: string // value type: int[10] // int[10][string] foo; // foo["a"] = new int[10]; // Range violation at runtime // foo["a"][0] = 1; // Range violation at runtime
Re: Does the compiler inline the predicate functions to std.algorithm.sort?
(@tipdbmp: The string gets turned into the function _D3std10functional__T9binaryFunVAyaa5_61203c2062VQra1_61VQza1_62Z__TQBvTiTiZQCdFNaNbNiNfKiKiZb. No references to it remain with -O3; the LLVM IR obtained with -output-ll might be easier to read than assembly.) I see. It seems that ldc 1.8.0 with "-release -O2|3" inlines it, but dmd 2.079.0 with "-release" (no -O option?) does not. the LLVM IR obtained with -output-ll might be easier to read than assembly.) I only seem to get assembly on d.godbolt.org, even with the -output-ll option.
Does the compiler inline the predicate functions to std.algorithm.sort?
I can't read assembly but it seems to me that it doesn't: https://godbolt.org/g/PCsnPT I think C++'s sort can take a "function object" that can get inlined.
Re: Local static variables must have unique names within a function's scope.
Mostly, it's just a bad idea - it's very easy for a person reading the code after you've written it to get the two x's mixed up. // example from: 19.17.1.3 void main() { { static int x; } { static int x; } // error { int i; } { int i; } // ok } I don't really see how the 'static' storage class would make 2 variables with the same name in different scopes "easier to mix up" compared to 2 variables with the same name in different scopes but declared without the 'static' keyword.
Local static variables must have unique names within a function's scope.
The following seems to work in C++, but errors in D, why is that? int foo(int* num) { { static int x = 10; x += 1; *num += x; } { static int x = 20; // error: foo.x is already defined in another scope in foo x += 2; *num += x; } return 0; } https://dlang.org/spec/function.html#local-static-variables
Re: Problem with function taking variable number of arguments with -m64
So is this a bug, or am I misunderstanding something?
Problem with function taking variable number of arguments with -m64
// // rdmd -m64 foo.d // module va_arg_x64_windows; void foo(void* a, void* b, void *c, void* d, ...) { import core.vararg : va_arg; import std.stdio : writeln; foreach (arg; _arguments) { if (arg == typeid(int)) { int x = va_arg!(int)(_argptr); writeln("x: ", x); } //else { //writeln("unknown arg type: ", arg.toString()); //} } } void main() { foo(null, null, null, null, 1234, 5678); // expected: // x: 1234 // x: 5678 // output: // x: 0 // x: 1234 }
Re: Is it possible to append to a local buffer without reallocating?
Appender is able to do this: It seems that Appender allocates its own private data: private struct Data { size_t capacity; Unqual!T[] arr; bool canExtend = false; } ... private Data* _data; ... _data = new Data; But hopefully its bug free unlike what I posted (missing `T.sizeof *` in the memcpy call).
Re: Is it possible to append to a local buffer without reallocating?
Have you checked what push_stuff actually returns with those inputs? Right, we get [0xFF, 0xFF, 'A'] and [0xFF, 0xFF]. I think the following is a pretty easy workaround though: alias usize = size_t; struct Push_Buf(T, usize stack_size) { T[stack_size] stack_buf; T[] heap_buf; usize p = 0; void opOpAssign(string op)(T e) if (op == "~") { if (p < stack_size) { stack_buf[p] = e; p += 1; } else { if (p == stack_size) { heap_buf = stack_buf.dup(); p += 1; } heap_buf ~= e; } } void opOpAssign(string op)(immutable(T)[] es) if (op == "~") { if (p + es.length <= stack_size) { import core.stdc.string : memcpy; memcpy(_buf[p], es.ptr, es.length); p += es.length; } else { if (p < stack_size) { heap_buf = stack_buf[0 .. p].dup(); p += es.length; } heap_buf ~= es; } } U opCast(U: T[])() { return as_slice(); } U opCast(U: immutable(T)[])() { return cast(immutable(T)[]) as_slice(); } @property T[] as_slice() { if (p <= stack_size) { return stack_buf[0 .. p]; } else return heap_buf; } alias as_slice this; } string push_stuff(usize buf_size)(ref Push_Buf!(char, buf_size) buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; } else { buf ~= 'A'; buf ~= 'B'; } return cast(string) buf; } void foo() { { Push_Buf!(char, 2) buf; string result = push_stuff(buf, 1); assert(buf.heap_buf.ptr == result.ptr); } { Push_Buf!(char, 2) buf; string result = push_stuff(buf, 0); assert(buf.stack_buf.ptr == result.ptr); } }
Is it possible to append to a local buffer without reallocating?
string push_stuff(char[] buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; return cast(string) buf[0 .. 3]; } else { buf ~= 'A'; buf ~= 'B'; return cast(string) buf[0 .. 2]; } } void foo() { { char[2] buf; string result = push_stuff(buf, 1); assert(buf.ptr != result.ptr); } { char[2] buf; string result = push_stuff(buf, 0); assert(buf.ptr == result.ptr); // <-- this assert fails } }
Is it possible to append to a local buffer without reallocating?
string push_stuff(char[] buf, int x) { if (x == 1) { buf ~= 'A'; buf ~= 'B'; buf ~= 'C'; return cast(string) buf[0 .. 3]; } else { buf ~= 'A'; buf ~= 'B'; return cast(string) buf[0 .. 2]; } } void foo() { { char[2] buf; string result = push_stuff(buf, 1); assert(buf.ptr != result.ptr); } { char[2] buf; string result = push_stuff(buf, 0); assert(buf.ptr == result.ptr); // <-- this assert fails } }
Re: Gc/D_runtime prevents dangling pointers?
What is your definition of a dangling pointer? A pointer pointing to freed memory, which presumably '[0]' should be because it reallocates. It seems that the '~=' operator "knows" that there's a reference to 'a's old memory and it keeps it around instead of freeing it. I just don't understand the mechanism behind this.
Gc/D_runtime prevents dangling pointers?
char * get_dangling_ptr() { char[] a; a.reserve(15); a ~= 'x'; char *x = [0]; auto a_initial_ptr = a.ptr; foreach (_; 0 .. 30) { a ~= 'y'; //a.assumeSafeAppend() ~= 'y'; } assert(a.ptr != a_initial_ptr, "a should've reallocated"); // trying to reuse 'a's old memory foreach (_; 0 .. 10) { char[] b; b.reserve(15); foreach (__; 0 .. 15) { b ~= 'y'; } } return x; } void main() { import std.stdio : writefln; char *x = get_dangling_ptr(); writefln("ptr: %X; value: %s", x, *x); } x doesn't seem to be a dangling pointer, how come?
Re: How to use the -I command line switch?
dmd main.d C:\libs\my_module.d That does not use the -I switch. It compiles if I specify the full path to my_module.d: dmd -IC:\libs main.d C:\libs\my_module.d I don't understand the error message though.
How to use the -I command line switch?
// C:\libs\my_module.d module my_module; void foo() {} // main.d module main; import my_module; void main() { foo(); } Running dmd with: dmd -IC:\libs main.d my_module.d I get: Error: module my_module is in file 'my_module.d' which cannot be read import path[0] = C:\libs import path[1] = path\to\dmd\D\dmd2\windows\bin\..\..\src\phobos import path[2] = path\to\dmd\D\dmd2\windows\bin\..\..\src\druntime\import
Re: std.file and non-English filename in Windows
I think you have to decode your input to UTF-8. stdin .byLineCopy(No.keepTerminator) .each!((string file_name_raw) { // change Latin1String to the code page of your console; // use the 'chcp' command to see the current code page of your console // import std.encoding; auto raw = cast(immutable( Latin1String)[]) file_name_raw; string file_name_utf8; transcode(raw, file_name_utf8); writefln("%s --> %s", file_name_utf8, file_name_utf8.exists); });
Calling a d-style-variadic-function from another
import core.vararg; string foo(fmt, ...) { int args_len = _arguments.length; if (args_len == 1) { if (typeid(_arguments[0] == typeid(TypeInfo[]))) { _arguments = va_arg!(TypeInfo[])(_argptr); args_len = _arguments.length; // how can I adjust _argptr? _argptr = ??? } } // using _arguments and va_arg!(X)(_argptr) here return "not implemented"; } void writef(string fmt, ...) { // write(foo(fmt, ...)); // <-- doesn't work // _arguments gets passed as a single argument of type TypeInfo[] write(foo(fmt, _arguments)); } https://dlang.org/spec/function.html#d_style_variadic_functions
Adding Toc for the "longish" spec pages.
It seems to me that some of the language reference/spec pages that are somewhat long, could provide a Toc (Table of contents) which should help users see an overview of what's there and improve the searchability and the navigation of the content. The 'Functions' page has a Toc already.