virtual destructor in C++ integration: bug or me being stupid?
cpp.cpp: class Oops { public: virtual ~Oops() {} virtual int number() const { return 42; } }; Oops* newOops() { return new Oops; } d.d: import std.stdio; extern(C++) { interface Oops { int number() const; } Oops newOops(); } void main() { auto oops = newOops(); writeln(oops.number()); } I get garbage in the output (I found this due to a crash in much more complicated code). If I comment out the virtual destructor, it works. It seems that the presence of the virtual destructor changes the layout and D doesn't know about it. Thinking about it now, it makes sense, how would D know? The problem here is that I don't know what the workaround is. Abstract classes in C++ usually have virtual destructors... Atila
Re: virtual destructor in C++ integration: bug or me being stupid?
On Tuesday, 29 December 2015 at 18:32:23 UTC, Atila Neves wrote: The problem here is that I don't know what the workaround is. The one I used (well, last time I tried this) was to just put a dummy function in the D interface that is a placeholder for it. interface C++Class { // at the same place as void _dontCallMeIamjustadestructor(); void other_function_you_actually_want(); }
Re: reduce a BitArray[]
On Tuesday, 29 December 2015 at 09:26:31 UTC, Alex wrote: The problem is, that the last line with the reduce does not compile. Why? If you get an error, it is imperative that you tell us what it is. For the record, this code: import std.bitmanip; import std.stdio; import std.algorithm; void main() { BitArray[] arr7 = [BitArray([0, 1, 0, 1, 0, 1]), BitArray([0, 1, 0, 0, 0, 0]), BitArray([0, 1, 0, 1, 0, 0]), BitArray([0, 1, 0, 1, 0, 0])]; BitArray common = BitArray([1,1,1,1,1,1]); foreach(BitArray ba; arr7) { common &= ba; } writeln("common2: ", common); writeln("common1: ", reduce!((a,b) => a & b)(arr7)); } Gives me the error: /opt/compilers/dmd2/include/std/algorithm/iteration.d(2570): Error: variable f868.main.F!(__lambda1).e cannot be declared to be a function /opt/compilers/dmd2/include/std/meta.d(546): Error: template instance f868.main.F!(__lambda1) error instantiating /opt/compilers/dmd2/include/std/algorithm/iteration.d(2477): instantiated from here: staticMap!(ReduceSeedType, __lambda1) /d486/f868.d(16):instantiated from here: reduce!(BitArray[]) /d486/f868.d(16): Error: template std.algorithm.iteration.reduce cannot deduce function from argument types !((a, b) => a & b)(BitArray[]), candidates are: /opt/compilers/dmd2/include/std/algorithm/iteration.d(2451): std.algorithm.iteration.reduce(fun...) if (fun.length >= 1) On 2.069.1 (dpaste: http://dpaste.dzfl.pl/8d7652e7ebeb). I don't have time ATM to diagnose it further. It definitely shouldn't be that cryptic of an error message.
Re: reduce a BitArray[]
V Tue, 29 Dec 2015 17:42:26 + Alex Parrill via Digitalmars-d-learnnapsáno: > On Tuesday, 29 December 2015 at 09:26:31 UTC, Alex wrote: > > The problem is, that the last line with the reduce does not > > compile. Why? > > If you get an error, it is imperative that you tell us what it is. > > For the record, this code: > > import std.bitmanip; > import std.stdio; > import std.algorithm; > > void main() { > > BitArray[] arr7 = [BitArray([0, 1, 0, 1, 0, 1]), > BitArray([0, 1, 0, 0, 0, 0]), BitArray([0, 1, 0, 1, 0, 0]), > BitArray([0, 1, 0, 1, 0, 0])]; > > BitArray common = BitArray([1,1,1,1,1,1]); > foreach(BitArray ba; arr7) > { > common &= ba; > } > writeln("common2: ", common); > > writeln("common1: ", reduce!((a,b) => a & b)(arr7)); > } > > Gives me the error: > > /opt/compilers/dmd2/include/std/algorithm/iteration.d(2570): > Error: variable f868.main.F!(__lambda1).e cannot be declared to > be a function > /opt/compilers/dmd2/include/std/meta.d(546): Error: template > instance f868.main.F!(__lambda1) error instantiating > /opt/compilers/dmd2/include/std/algorithm/iteration.d(2477): >instantiated from here: staticMap!(ReduceSeedType, __lambda1) > /d486/f868.d(16):instantiated from here: > reduce!(BitArray[]) > /d486/f868.d(16): Error: template std.algorithm.iteration.reduce > cannot deduce function from argument types !((a, b) => a & > b)(BitArray[]), candidates are: > /opt/compilers/dmd2/include/std/algorithm/iteration.d(2451): >std.algorithm.iteration.reduce(fun...) if (fun.length >= 1) > > On 2.069.1 (dpaste: http://dpaste.dzfl.pl/8d7652e7ebeb). I don't > have time ATM to diagnose it further. It definitely shouldn't be > that cryptic of an error message. It is cause by this https://dlang.org/phobos/std_bitmanip.html#.BitArray.init So until it will be removed it will does not compile. Problem is in https://dlang.org/phobos/std_range_primitives.html#.ElementType which is implementet as template ElementType(R) { static if (is(typeof(R.init.front.init) T)) alias ElementType = T; else alias ElementType = void; } maybe rewriting this like: template ElementType(R) { static if (is(typeof(R.init.front) T)) alias ElementType = T; else alias ElementType = void; } could help too
Unexpected ' ' when converting from type string to type int
Hello, thanks for stopping in. I am fuddling through some exercises on a certain website, and I have come across a very frustrating bug I can't seem to fix. The Problem: Given a square matrix of size N×N, calculate the absolute difference between the sums of its diagonals. Sample Input: 3 11 2 4 4 5 6 10 8 -12 First line is N, and the expected result of this example is 15. If I hardcode in the value for N, this code works just peachy. It's when I am trying to actually read in the value of the first line from stdin that I am having a problem. I seem to be unable to convert the string input to an integer to use later on. The code: import std.stdio, std.math, std.string, std.conv; void main(){ auto matrix_size = readln; //below I have commented out the offending call to to!int and replaced it with a hardcoded value 3 in order to force it to work. auto ms = 3;//matrix_size.to!int; int[][] matrix = new int[][ms]; for(int i = 0; i < ms; i++){ string[] string_nums = readln.split; foreach (num; string_nums){ auto value = num.to!int; matrix[i] ~= value; } } int primary_sum = 0; int secondary_sum = 0; int j = 0; int i = ms - 1; //determine diagonal sums for(int row = 0; row < ms; ++row){ primary_sum += matrix[row][j]; secondary_sum += matrix[row][i]; ++j; --i; } auto result = abs(primary_sum - secondary_sum); result.writeln; }
Re: Unexpected ' ' when converting from type string to type int
On Wednesday, 30 December 2015 at 01:36:56 UTC, Michael S wrote: auto matrix_size = readln; Change that to auto matrix_size = readln.strip; and you should be in business. readln() returns any leading spaces and the newline character at the end of the line too, which is why to is throwing. The .strip function will trim that whitespace off.
Re: Unexpected ' ' when converting from type string to type int
On Wednesday, 30 December 2015 at 01:38:32 UTC, Adam D. Ruppe wrote: On Wednesday, 30 December 2015 at 01:36:56 UTC, Michael S wrote: auto matrix_size = readln; Change that to auto matrix_size = readln.strip; and you should be in business. readln() returns any leading spaces and the newline character at the end of the line too, which is why to is throwing. The .strip function will trim that whitespace off. Wow thank you Adam. I didn't expect to have a reply so quickly, especially a slam dunk like that one. It works perfectly now!
Re: Is stdout.flush() unsafe?
On 12/29/15 4:57 AM, tsbockman wrote: Trying to compile this: void main() @safe { import std.stdio; stdout.flush(); } Fails with this message: Error: safe function 'main' cannot access __gshared data 'stdout' Is this necessary? If so, what are the synchronization requirements for access to `stdout`? Hm... what is needed is an accessor for stdout: void main() @safe { import std.stdio; auto safe_stdout() @trusted { return stdout; } safe_stdout.flush(); } The issue is the storage class __gshared is banned from accessing in safe code (because it is subject to races). So you have to claim to the compiler "I know this is generally not safe, but I have encapsulated it in a way to make it safe". Likely, this is what we should do for all the standard streams, not being able to access streams in safe code seems a steep restriction. -Steve
pragma(inline)
Hi, Does `pragma(inline, true)` force DMD compiler to inline function when `-inline` was _not_ defined? I am failing to get a good disassembled code with obj2asm/otool :-( Best, Ilya
reduce a BitArray[]
Hi there, a silly question from me for the turn of the year... I apparently missing the forest through the trees. The first part of the code works as expected: [code] int[] arr8 = [1,2,3,4,5]; int sum = 0; foreach(int summand; arr8) { sum += summand; } writeln("sum1: ", sum); writeln("sum2: ", reduce!((a,b) => a + b)(arr8)); [/code] The second one does not: [code] import std.bitmanip; BitArray[] arr7 = [BitArray([0, 1, 0, 1, 0, 1]), BitArray([0, 1, 0, 0, 0, 0]), BitArray([0, 1, 0, 1, 0, 0]), BitArray([0, 1, 0, 1, 0, 0])]; BitArray common = BitArray([1,1,1,1,1,1]); foreach(BitArray ba; arr7) { common &= ba; } writeln("common2: ", common); //writeln("common1: ", reduce!((a,b) => a & b)(arr7)); [/code] The problem is, that the last line with the reduce does not compile. Why?
Is stdout.flush() unsafe?
Trying to compile this: void main() @safe { import std.stdio; stdout.flush(); } Fails with this message: Error: safe function 'main' cannot access __gshared data 'stdout' Is this necessary? If so, what are the synchronization requirements for access to `stdout`?